radeon_cs: move to inline cs_write_dword
[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 LOCK_HARDWARE(rmesa);
625 ret = rcommonFlushCmdBufLocked(rmesa, caller);
626 UNLOCK_HARDWARE(rmesa);
627
628 if (ret) {
629 fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret);
630 _mesa_exit(ret);
631 }
632
633 return ret;
634 }
635
636 /**
637 * Make sure that enough space is available in the command buffer
638 * by flushing if necessary.
639 *
640 * \param dwords The number of dwords we need to be free on the command buffer
641 */
642 void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
643 {
644 if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size ||
645 radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
646 rcommonFlushCmdBuf(rmesa, caller);
647 }
648 }
649
650 void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size)
651 {
652 GLuint 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;
658 }
659 if (size > 64 * 256)
660 size = 64 * 256;
661
662 size = 64 * 1024 / 4;
663
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));
669 fprintf(stderr,
670 "Allocating %d bytes command buffer (max state is %d bytes)\n",
671 size * 4, max_state_size * 4);
672 }
673
674 if (rmesa->radeonScreen->kernel_mm) {
675 int fd = rmesa->radeonScreen->driScreen->fd;
676 rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd);
677 } else {
678 rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa);
679 }
680 if (rmesa->cmdbuf.csm == NULL) {
681 /* FIXME: fatal error */
682 return;
683 }
684 rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
685 assert(rmesa->cmdbuf.cs != NULL);
686 rmesa->cmdbuf.size = size;
687
688 if (!rmesa->radeonScreen->kernel_mm) {
689 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
690 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
691 } else {
692 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
693 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
694 }
695
696 }
697 /**
698 * Destroy the command buffer
699 */
700 void rcommonDestroyCmdBuf(radeonContextPtr rmesa)
701 {
702 radeon_cs_destroy(rmesa->cmdbuf.cs);
703 if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) {
704 radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm);
705 } else {
706 radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm);
707 }
708 }
709
710 void rcommonBeginBatch(radeonContextPtr rmesa, int n,
711 int dostate,
712 const char *file,
713 const char *function,
714 int line)
715 {
716 rcommonEnsureCmdBufSpace(rmesa, n, function);
717 if (!rmesa->cmdbuf.cs->cdw && dostate) {
718 if (RADEON_DEBUG & DEBUG_IOCTL)
719 fprintf(stderr, "Reemit state after flush (from %s)\n", function);
720 rmesa->vtbl.emit_state(rmesa);
721 }
722 radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line);
723 }
724
725
726
727 /* Return various strings for glGetString().
728 */
729 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
730 {
731 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
732 static char buffer[128];
733
734 switch (name) {
735 case GL_VENDOR:
736 if (IS_R300_CLASS(radeon->radeonScreen))
737 return (GLubyte *) "DRI R300 Project";
738 else
739 return (GLubyte *) "Tungsten Graphics, Inc.";
740
741 case GL_RENDERER:
742 {
743 unsigned offset;
744 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
745 radeon->radeonScreen->AGPMode;
746 const char* chipname;
747
748
749
750 if (IS_R300_CLASS(radeon->radeonScreen))
751 chipname = "R300";
752 else
753 chipname = "R200";
754
755 offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
756 agp_mode);
757
758 if (IS_R300_CLASS(radeon->radeonScreen)) {
759 sprintf(&buffer[offset], " %sTCL",
760 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
761 ? "" : "NO-");
762 } else {
763 sprintf(&buffer[offset], " %sTCL",
764 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
765 ? "" : "NO-");
766 }
767
768 if (radeon->radeonScreen->driScreen->dri2.enabled)
769 strcat(buffer, " DRI2");
770
771 return (GLubyte *) buffer;
772 }
773
774 default:
775 return NULL;
776 }
777 }
778
779 /* Initialize the driver's misc functions.
780 */
781 static void radeonInitDriverFuncs(struct dd_function_table *functions)
782 {
783 functions->GetString = radeonGetString;
784 }
785
786 /**
787 * Create and initialize all common fields of the context,
788 * including the Mesa context itself.
789 */
790 GLboolean radeonInitContext(radeonContextPtr radeon,
791 struct dd_function_table* functions,
792 const __GLcontextModes * glVisual,
793 __DRIcontextPrivate * driContextPriv,
794 void *sharedContextPrivate)
795 {
796 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
797 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
798 GLcontext* ctx;
799 GLcontext* shareCtx;
800 int fthrottle_mode;
801
802 /* Fill in additional standard functions. */
803 radeonInitDriverFuncs(functions);
804
805 radeon->radeonScreen = screen;
806 /* Allocate and initialize the Mesa context */
807 if (sharedContextPrivate)
808 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
809 else
810 shareCtx = NULL;
811 radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
812 functions, (void *)radeon);
813 if (!radeon->glCtx)
814 return GL_FALSE;
815
816 ctx = radeon->glCtx;
817 driContextPriv->driverPrivate = radeon;
818
819 /* DRI fields */
820 radeon->dri.context = driContextPriv;
821 radeon->dri.screen = sPriv;
822 radeon->dri.drawable = NULL;
823 radeon->dri.readable = NULL;
824 radeon->dri.hwContext = driContextPriv->hHWContext;
825 radeon->dri.hwLock = &sPriv->pSAREA->lock;
826 radeon->dri.fd = sPriv->fd;
827 radeon->dri.drmMinor = sPriv->drm_version.minor;
828
829 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
830 screen->sarea_priv_offset);
831
832 /* Setup IRQs */
833 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
834 radeon->iw.irq_seq = -1;
835 radeon->irqsEmitted = 0;
836 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
837 radeon->radeonScreen->irq);
838
839 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
840
841 if (!radeon->do_irqs)
842 fprintf(stderr,
843 "IRQ's not enabled, falling back to %s: %d %d\n",
844 radeon->do_usleeps ? "usleeps" : "busy waits",
845 fthrottle_mode, radeon->radeonScreen->irq);
846
847 (*sPriv->systemTime->getUST) (&radeon->swap_ust);
848
849 return GL_TRUE;
850 }
851
852 /**
853 * Cleanup common context fields.
854 * Called by r200DestroyContext/r300DestroyContext
855 */
856 void radeonCleanupContext(radeonContextPtr radeon)
857 {
858 FILE *track;
859 struct radeon_renderbuffer *rb;
860 GLframebuffer *fb;
861
862 fb = (void*)radeon->dri.drawable->driverPrivate;
863 rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
864 if (rb && rb->bo) {
865 radeon_bo_unref(rb->bo);
866 rb->bo = NULL;
867 }
868 rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
869 if (rb && rb->bo) {
870 radeon_bo_unref(rb->bo);
871 rb->bo = NULL;
872 }
873 rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
874 if (rb && rb->bo) {
875 radeon_bo_unref(rb->bo);
876 rb->bo = NULL;
877 }
878 fb = (void*)radeon->dri.readable->driverPrivate;
879 rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
880 if (rb && rb->bo) {
881 radeon_bo_unref(rb->bo);
882 rb->bo = NULL;
883 }
884 rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
885 if (rb && rb->bo) {
886 radeon_bo_unref(rb->bo);
887 rb->bo = NULL;
888 }
889 rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
890 if (rb && rb->bo) {
891 radeon_bo_unref(rb->bo);
892 rb->bo = NULL;
893 }
894
895 /* _mesa_destroy_context() might result in calls to functions that
896 * depend on the DriverCtx, so don't set it to NULL before.
897 *
898 * radeon->glCtx->DriverCtx = NULL;
899 */
900
901 /* free the Mesa context */
902 _mesa_destroy_context(radeon->glCtx);
903
904 /* free the option cache */
905 driDestroyOptionCache(&radeon->optionCache);
906
907 if (radeon->state.scissor.pClipRects) {
908 FREE(radeon->state.scissor.pClipRects);
909 radeon->state.scissor.pClipRects = 0;
910 }
911 track = fopen("/tmp/tracklog", "w");
912 if (track) {
913 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
914 fclose(track);
915 }
916 }
917
918 static void
919 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
920 GLframebuffer *draw)
921 {
922 /* if radeon->fake */
923 struct radeon_renderbuffer *rb;
924
925 if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
926
927 if (!rb->bo) {
928 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
929 radeon->radeonScreen->frontOffset,
930 0,
931 0,
932 RADEON_GEM_DOMAIN_VRAM,
933 0);
934 }
935 rb->cpp = radeon->radeonScreen->cpp;
936 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
937 }
938 if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
939 if (!rb->bo) {
940 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
941 radeon->radeonScreen->backOffset,
942 0,
943 0,
944 RADEON_GEM_DOMAIN_VRAM,
945 0);
946 }
947 rb->cpp = radeon->radeonScreen->cpp;
948 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
949 }
950 if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
951 if (!rb->bo) {
952 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
953 radeon->radeonScreen->depthOffset,
954 0,
955 0,
956 RADEON_GEM_DOMAIN_VRAM,
957 0);
958 }
959 rb->cpp = radeon->radeonScreen->cpp;
960 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
961 }
962 }
963
964 static void
965 radeon_make_renderbuffer_current(radeonContextPtr radeon,
966 GLframebuffer *draw)
967 {
968 int size = 4096*4096*4;
969 /* if radeon->fake */
970 struct radeon_renderbuffer *rb;
971
972 if (radeon->radeonScreen->kernel_mm) {
973 radeon_make_kernel_renderbuffer_current(radeon, draw);
974 return;
975 }
976
977
978 if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
979 if (!rb->bo) {
980 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
981 radeon->radeonScreen->frontOffset +
982 radeon->radeonScreen->fbLocation,
983 size,
984 4096,
985 RADEON_GEM_DOMAIN_VRAM,
986 0);
987 }
988 rb->cpp = radeon->radeonScreen->cpp;
989 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
990 }
991 if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
992 if (!rb->bo) {
993 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
994 radeon->radeonScreen->backOffset +
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->backPitch * rb->cpp;
1003 }
1004 if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
1005 if (!rb->bo) {
1006 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1007 radeon->radeonScreen->depthOffset +
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->depthPitch * rb->cpp;
1016 }
1017 }
1018
1019
1020 void
1021 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
1022 {
1023 unsigned int attachments[10];
1024 __DRIbuffer *buffers;
1025 __DRIscreen *screen;
1026 struct radeon_renderbuffer *rb;
1027 int i, count;
1028 GLframebuffer *draw;
1029 radeonContextPtr radeon;
1030
1031 draw = drawable->driverPrivate;
1032 screen = context->driScreenPriv;
1033 radeon = (radeonContextPtr) context->driverPrivate;
1034 i = 0;
1035 if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
1036 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
1037 }
1038 if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
1039 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
1040 }
1041 if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
1042 attachments[i++] = __DRI_BUFFER_DEPTH;
1043 }
1044
1045 buffers = (*screen->dri2.loader->getBuffers)(drawable,
1046 &drawable->w,
1047 &drawable->h,
1048 attachments, i,
1049 &count,
1050 drawable->loaderPrivate);
1051 if (buffers == NULL)
1052 return;
1053
1054 /* set one cliprect to cover the whole drawable */
1055 drawable->x = 0;
1056 drawable->y = 0;
1057 drawable->backX = 0;
1058 drawable->backY = 0;
1059 drawable->numClipRects = 1;
1060 drawable->pClipRects[0].x1 = 0;
1061 drawable->pClipRects[0].y1 = 0;
1062 drawable->pClipRects[0].x2 = drawable->w;
1063 drawable->pClipRects[0].y2 = drawable->h;
1064 drawable->numBackClipRects = 1;
1065 drawable->pBackClipRects[0].x1 = 0;
1066 drawable->pBackClipRects[0].y1 = 0;
1067 drawable->pBackClipRects[0].x2 = drawable->w;
1068 drawable->pBackClipRects[0].y2 = drawable->h;
1069 for (i = 0; i < count; i++) {
1070 switch (buffers[i].attachment) {
1071 case __DRI_BUFFER_FRONT_LEFT:
1072 rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
1073 if (rb->bo) {
1074 radeon_bo_unref(rb->bo);
1075 rb->bo = NULL;
1076 }
1077 rb->cpp = buffers[i].cpp;
1078 rb->pitch = buffers[i].pitch;
1079 rb->width = drawable->w;
1080 rb->height = drawable->h;
1081 rb->has_surface = 0;
1082 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1083 buffers[i].name,
1084 0,
1085 0,
1086 RADEON_GEM_DOMAIN_VRAM,
1087 buffers[i].flags);
1088 if (rb->bo == NULL) {
1089 fprintf(stderr, "failled to attach front %d\n",
1090 buffers[i].name);
1091 }
1092 break;
1093 case __DRI_BUFFER_BACK_LEFT:
1094 rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
1095 if (rb->bo) {
1096 radeon_bo_unref(rb->bo);
1097 rb->bo = NULL;
1098 }
1099 rb->cpp = buffers[i].cpp;
1100 rb->pitch = buffers[i].pitch;
1101 rb->width = drawable->w;
1102 rb->height = drawable->h;
1103 rb->has_surface = 0;
1104 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1105 buffers[i].name,
1106 0,
1107 0,
1108 RADEON_GEM_DOMAIN_VRAM,
1109 buffers[i].flags);
1110 break;
1111 case __DRI_BUFFER_DEPTH:
1112 rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer;
1113 if (rb->bo) {
1114 radeon_bo_unref(rb->bo);
1115 rb->bo = NULL;
1116 }
1117 rb->cpp = buffers[i].cpp;
1118 rb->pitch = buffers[i].pitch;
1119 rb->width = drawable->w;
1120 rb->height = drawable->h;
1121 rb->has_surface = 0;
1122 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1123 buffers[i].name,
1124 0,
1125 0,
1126 RADEON_GEM_DOMAIN_VRAM,
1127 buffers[i].flags);
1128 break;
1129 case __DRI_BUFFER_STENCIL:
1130 break;
1131 case __DRI_BUFFER_ACCUM:
1132 default:
1133 fprintf(stderr,
1134 "unhandled buffer attach event, attacment type %d\n",
1135 buffers[i].attachment);
1136 return;
1137 }
1138 }
1139 radeon = (radeonContextPtr) context->driverPrivate;
1140 driUpdateFramebufferSize(radeon->glCtx, drawable);
1141 }
1142
1143 /* Force the context `c' to be the current context and associate with it
1144 * buffer `b'.
1145 */
1146 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
1147 __DRIdrawablePrivate * driDrawPriv,
1148 __DRIdrawablePrivate * driReadPriv)
1149 {
1150 radeonContextPtr radeon;
1151 GLframebuffer *dfb, *rfb;
1152
1153 if (!driContextPriv) {
1154 if (RADEON_DEBUG & DEBUG_DRI)
1155 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
1156 _mesa_make_current(NULL, NULL, NULL);
1157 return GL_TRUE;
1158 }
1159 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
1160 dfb = driDrawPriv->driverPrivate;
1161 rfb = driReadPriv->driverPrivate;
1162
1163 if (driContextPriv->driScreenPriv->dri2.enabled) {
1164 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
1165 if (driDrawPriv != driReadPriv)
1166 radeon_update_renderbuffers(driContextPriv, driReadPriv);
1167 radeon->state.color.rrb =
1168 (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
1169 radeon->state.depth.rrb =
1170 (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer;
1171 }
1172
1173
1174 if (RADEON_DEBUG & DEBUG_DRI)
1175 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, radeon->glCtx);
1176
1177 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
1178 if (driReadPriv != driDrawPriv)
1179 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
1180
1181 if (!driContextPriv->driScreenPriv->dri2.enabled) {
1182 radeon_make_renderbuffer_current(radeon, dfb);
1183 }
1184
1185 _mesa_make_current(radeon->glCtx, dfb, rfb);
1186
1187 if (radeon->dri.drawable != driDrawPriv) {
1188 if (driDrawPriv->swap_interval == (unsigned)-1) {
1189 driDrawPriv->vblFlags =
1190 (radeon->radeonScreen->irq != 0)
1191 ? driGetDefaultVBlankFlags(&radeon->
1192 optionCache)
1193 : VBLANK_FLAG_NO_IRQ;
1194
1195 driDrawableInitVBlank(driDrawPriv);
1196 }
1197 }
1198
1199 radeon->dri.readable = driReadPriv;
1200
1201 if (radeon->dri.drawable != driDrawPriv ||
1202 radeon->lastStamp != driDrawPriv->lastStamp) {
1203 radeon->dri.drawable = driDrawPriv;
1204
1205 radeonSetCliprects(radeon);
1206 radeon->vtbl.update_viewport_offset(radeon->glCtx);
1207 }
1208
1209 _mesa_update_state(radeon->glCtx);
1210
1211 if (!driContextPriv->driScreenPriv->dri2.enabled) {
1212 radeonUpdatePageFlipping(radeon);
1213 }
1214
1215 if (RADEON_DEBUG & DEBUG_DRI)
1216 fprintf(stderr, "End %s\n", __FUNCTION__);
1217 return GL_TRUE;
1218 }
1219
1220
1221 #if defined(USE_X86_ASM)
1222 #define COPY_DWORDS( dst, src, nr ) \
1223 do { \
1224 int __tmp; \
1225 __asm__ __volatile__( "rep ; movsl" \
1226 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
1227 : "0" (nr), \
1228 "D" ((long)dst), \
1229 "S" ((long)src) ); \
1230 } while (0)
1231 #else
1232 #define COPY_DWORDS( dst, src, nr ) \
1233 do { \
1234 int j; \
1235 for ( j = 0 ; j < nr ; j++ ) \
1236 dst[j] = ((int *)src)[j]; \
1237 dst += nr; \
1238 } while (0)
1239 #endif
1240
1241 static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count)
1242 {
1243 int i;
1244
1245 if (RADEON_DEBUG & DEBUG_VERTS)
1246 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1247 __FUNCTION__, count, stride, (void *)out, (void *)data);
1248
1249 if (stride == 4)
1250 COPY_DWORDS(out, data, count);
1251 else
1252 for (i = 0; i < count; i++) {
1253 out[0] = *(int *)data;
1254 out++;
1255 data += stride;
1256 }
1257 }
1258
1259 static void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count)
1260 {
1261 int i;
1262
1263 if (RADEON_DEBUG & DEBUG_VERTS)
1264 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1265 __FUNCTION__, count, stride, (void *)out, (void *)data);
1266
1267 if (stride == 8)
1268 COPY_DWORDS(out, data, count * 2);
1269 else
1270 for (i = 0; i < count; i++) {
1271 out[0] = *(int *)data;
1272 out[1] = *(int *)(data + 4);
1273 out += 2;
1274 data += stride;
1275 }
1276 }
1277
1278 static void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count)
1279 {
1280 int i;
1281
1282 if (RADEON_DEBUG & DEBUG_VERTS)
1283 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1284 __FUNCTION__, count, stride, (void *)out, (void *)data);
1285
1286 if (stride == 12) {
1287 COPY_DWORDS(out, data, count * 3);
1288 }
1289 else
1290 for (i = 0; i < count; i++) {
1291 out[0] = *(int *)data;
1292 out[1] = *(int *)(data + 4);
1293 out[2] = *(int *)(data + 8);
1294 out += 3;
1295 data += stride;
1296 }
1297 }
1298
1299 static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count)
1300 {
1301 int i;
1302
1303 if (RADEON_DEBUG & DEBUG_VERTS)
1304 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1305 __FUNCTION__, count, stride, (void *)out, (void *)data);
1306
1307 if (stride == 16)
1308 COPY_DWORDS(out, data, count * 4);
1309 else
1310 for (i = 0; i < count; i++) {
1311 out[0] = *(int *)data;
1312 out[1] = *(int *)(data + 4);
1313 out[2] = *(int *)(data + 8);
1314 out[3] = *(int *)(data + 12);
1315 out += 4;
1316 data += stride;
1317 }
1318 }
1319
1320 void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
1321 GLvoid * data, int size, int stride, int count)
1322 {
1323 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1324 uint32_t *out;
1325
1326 if (stride == 0) {
1327 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
1328 count = 1;
1329 aos->stride = 0;
1330 } else {
1331 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
1332 aos->stride = size;
1333 }
1334
1335 aos->components = size;
1336 aos->count = count;
1337
1338 out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
1339 switch (size) {
1340 case 1: radeonEmitVec4(out, data, stride, count); break;
1341 case 2: radeonEmitVec8(out, data, stride, count); break;
1342 case 3: radeonEmitVec12(out, data, stride, count); break;
1343 case 4: radeonEmitVec16(out, data, stride, count); break;
1344 default:
1345 assert(0);
1346 break;
1347 }
1348 }
1349
1350
1351 void radeon_print_state_atom( struct radeon_state_atom *state )
1352 {
1353 int i;
1354
1355 fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
1356
1357 if (RADEON_DEBUG & DEBUG_VERBOSE)
1358 for (i = 0 ; i < state->cmd_size ; i++)
1359 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
1360
1361 }
1362
1363 /* textures */
1364 /**
1365 * Allocate an empty texture image object.
1366 */
1367 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
1368 {
1369 return CALLOC(sizeof(radeon_texture_image));
1370 }
1371
1372 /**
1373 * Free memory associated with this texture image.
1374 */
1375 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
1376 {
1377 radeon_texture_image* image = get_radeon_texture_image(timage);
1378
1379 if (image->mt) {
1380 radeon_miptree_unreference(image->mt);
1381 image->mt = 0;
1382 assert(!image->base.Data);
1383 } else {
1384 _mesa_free_texture_image_data(ctx, timage);
1385 }
1386 if (image->bo) {
1387 radeon_bo_unref(image->bo);
1388 image->bo = NULL;
1389 }
1390 }
1391
1392 /* Set Data pointer and additional data for mapped texture image */
1393 static void teximage_set_map_data(radeon_texture_image *image)
1394 {
1395 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
1396 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
1397 image->base.RowStride = lvl->rowstride / image->mt->bpp;
1398 }
1399
1400
1401 /**
1402 * Map a single texture image for glTexImage and friends.
1403 */
1404 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
1405 {
1406 if (image->mt) {
1407 assert(!image->base.Data);
1408
1409 radeon_bo_map(image->mt->bo, write_enable);
1410 teximage_set_map_data(image);
1411 }
1412 }
1413
1414
1415 void radeon_teximage_unmap(radeon_texture_image *image)
1416 {
1417 if (image->mt) {
1418 assert(image->base.Data);
1419
1420 image->base.Data = 0;
1421 radeon_bo_unmap(image->mt->bo);
1422 }
1423 }
1424
1425 /**
1426 * Map a validated texture for reading during software rendering.
1427 */
1428 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
1429 {
1430 radeonTexObj* t = radeon_tex_obj(texObj);
1431 int face, level;
1432
1433 assert(texObj->_Complete);
1434 assert(t->mt);
1435
1436 radeon_bo_map(t->mt->bo, GL_FALSE);
1437 for(face = 0; face < t->mt->faces; ++face) {
1438 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
1439 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
1440 }
1441 }
1442
1443 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
1444 {
1445 radeonTexObj* t = radeon_tex_obj(texObj);
1446 int face, level;
1447
1448 assert(texObj->_Complete);
1449 assert(t->mt);
1450
1451 for(face = 0; face < t->mt->faces; ++face) {
1452 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
1453 texObj->Image[face][level]->Data = 0;
1454 }
1455 radeon_bo_unmap(t->mt->bo);
1456 }
1457
1458 GLuint radeon_face_for_target(GLenum target)
1459 {
1460 switch (target) {
1461 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1462 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1463 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1464 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1465 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1466 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1467 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1468 default:
1469 return 0;
1470 }
1471 }
1472
1473 /**
1474 * Wraps Mesa's implementation to ensure that the base level image is mapped.
1475 *
1476 * This relies on internal details of _mesa_generate_mipmap, in particular
1477 * the fact that the memory for recreated texture images is always freed.
1478 */
1479 void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
1480 struct gl_texture_object *texObj)
1481 {
1482 radeonTexObj* t = radeon_tex_obj(texObj);
1483 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1484 int i, face;
1485
1486
1487 _mesa_generate_mipmap(ctx, target, texObj);
1488
1489 for (face = 0; face < nr_faces; face++) {
1490 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
1491 radeon_texture_image *image;
1492
1493 image = get_radeon_texture_image(texObj->Image[face][i]);
1494
1495 if (image == NULL)
1496 break;
1497
1498 image->mtlevel = i;
1499 image->mtface = face;
1500
1501 radeon_miptree_unreference(image->mt);
1502 image->mt = NULL;
1503 }
1504 }
1505
1506 }
1507
1508 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
1509 {
1510 GLuint face = radeon_face_for_target(target);
1511 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
1512
1513 radeon_teximage_map(baseimage, GL_FALSE);
1514 radeon_generate_mipmap(ctx, target, texObj);
1515 radeon_teximage_unmap(baseimage);
1516 }
1517
1518
1519 /* try to find a format which will only need a memcopy */
1520 static const struct gl_texture_format *radeonChoose8888TexFormat(GLenum srcFormat,
1521 GLenum srcType)
1522 {
1523 const GLuint ui = 1;
1524 const GLubyte littleEndian = *((const GLubyte *)&ui);
1525
1526 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1527 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1528 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1529 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
1530 return &_mesa_texformat_rgba8888;
1531 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1532 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1533 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1534 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
1535 return &_mesa_texformat_rgba8888_rev;
1536 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1537 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1538 return &_mesa_texformat_argb8888_rev;
1539 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1540 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1541 return &_mesa_texformat_argb8888;
1542 } else
1543 return _dri_texformat_argb8888;
1544 }
1545
1546 const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
1547 GLint internalFormat,
1548 GLenum format,
1549 GLenum type)
1550 {
1551 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1552 const GLboolean do32bpt =
1553 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
1554 const GLboolean force16bpt =
1555 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
1556 (void)format;
1557
1558 #if 0
1559 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
1560 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
1561 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
1562 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
1563 #endif
1564
1565 switch (internalFormat) {
1566 case 4:
1567 case GL_RGBA:
1568 case GL_COMPRESSED_RGBA:
1569 switch (type) {
1570 case GL_UNSIGNED_INT_10_10_10_2:
1571 case GL_UNSIGNED_INT_2_10_10_10_REV:
1572 return do32bpt ? _dri_texformat_argb8888 :
1573 _dri_texformat_argb1555;
1574 case GL_UNSIGNED_SHORT_4_4_4_4:
1575 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
1576 return _dri_texformat_argb4444;
1577 case GL_UNSIGNED_SHORT_5_5_5_1:
1578 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
1579 return _dri_texformat_argb1555;
1580 default:
1581 return do32bpt ? radeonChoose8888TexFormat(format, type) :
1582 _dri_texformat_argb4444;
1583 }
1584
1585 case 3:
1586 case GL_RGB:
1587 case GL_COMPRESSED_RGB:
1588 switch (type) {
1589 case GL_UNSIGNED_SHORT_4_4_4_4:
1590 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
1591 return _dri_texformat_argb4444;
1592 case GL_UNSIGNED_SHORT_5_5_5_1:
1593 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
1594 return _dri_texformat_argb1555;
1595 case GL_UNSIGNED_SHORT_5_6_5:
1596 case GL_UNSIGNED_SHORT_5_6_5_REV:
1597 return _dri_texformat_rgb565;
1598 default:
1599 return do32bpt ? _dri_texformat_argb8888 :
1600 _dri_texformat_rgb565;
1601 }
1602
1603 case GL_RGBA8:
1604 case GL_RGB10_A2:
1605 case GL_RGBA12:
1606 case GL_RGBA16:
1607 return !force16bpt ?
1608 radeonChoose8888TexFormat(format,
1609 type) : _dri_texformat_argb4444;
1610
1611 case GL_RGBA4:
1612 case GL_RGBA2:
1613 return _dri_texformat_argb4444;
1614
1615 case GL_RGB5_A1:
1616 return _dri_texformat_argb1555;
1617
1618 case GL_RGB8:
1619 case GL_RGB10:
1620 case GL_RGB12:
1621 case GL_RGB16:
1622 return !force16bpt ? _dri_texformat_argb8888 :
1623 _dri_texformat_rgb565;
1624
1625 case GL_RGB5:
1626 case GL_RGB4:
1627 case GL_R3_G3_B2:
1628 return _dri_texformat_rgb565;
1629
1630 case GL_ALPHA:
1631 case GL_ALPHA4:
1632 case GL_ALPHA8:
1633 case GL_ALPHA12:
1634 case GL_ALPHA16:
1635 case GL_COMPRESSED_ALPHA:
1636 return _dri_texformat_a8;
1637
1638 case 1:
1639 case GL_LUMINANCE:
1640 case GL_LUMINANCE4:
1641 case GL_LUMINANCE8:
1642 case GL_LUMINANCE12:
1643 case GL_LUMINANCE16:
1644 case GL_COMPRESSED_LUMINANCE:
1645 return _dri_texformat_l8;
1646
1647 case 2:
1648 case GL_LUMINANCE_ALPHA:
1649 case GL_LUMINANCE4_ALPHA4:
1650 case GL_LUMINANCE6_ALPHA2:
1651 case GL_LUMINANCE8_ALPHA8:
1652 case GL_LUMINANCE12_ALPHA4:
1653 case GL_LUMINANCE12_ALPHA12:
1654 case GL_LUMINANCE16_ALPHA16:
1655 case GL_COMPRESSED_LUMINANCE_ALPHA:
1656 return _dri_texformat_al88;
1657
1658 case GL_INTENSITY:
1659 case GL_INTENSITY4:
1660 case GL_INTENSITY8:
1661 case GL_INTENSITY12:
1662 case GL_INTENSITY16:
1663 case GL_COMPRESSED_INTENSITY:
1664 return _dri_texformat_i8;
1665
1666 case GL_YCBCR_MESA:
1667 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
1668 type == GL_UNSIGNED_BYTE)
1669 return &_mesa_texformat_ycbcr;
1670 else
1671 return &_mesa_texformat_ycbcr_rev;
1672
1673 case GL_RGB_S3TC:
1674 case GL_RGB4_S3TC:
1675 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1676 return &_mesa_texformat_rgb_dxt1;
1677
1678 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1679 return &_mesa_texformat_rgba_dxt1;
1680
1681 case GL_RGBA_S3TC:
1682 case GL_RGBA4_S3TC:
1683 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1684 return &_mesa_texformat_rgba_dxt3;
1685
1686 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1687 return &_mesa_texformat_rgba_dxt5;
1688
1689 case GL_ALPHA16F_ARB:
1690 return &_mesa_texformat_alpha_float16;
1691 case GL_ALPHA32F_ARB:
1692 return &_mesa_texformat_alpha_float32;
1693 case GL_LUMINANCE16F_ARB:
1694 return &_mesa_texformat_luminance_float16;
1695 case GL_LUMINANCE32F_ARB:
1696 return &_mesa_texformat_luminance_float32;
1697 case GL_LUMINANCE_ALPHA16F_ARB:
1698 return &_mesa_texformat_luminance_alpha_float16;
1699 case GL_LUMINANCE_ALPHA32F_ARB:
1700 return &_mesa_texformat_luminance_alpha_float32;
1701 case GL_INTENSITY16F_ARB:
1702 return &_mesa_texformat_intensity_float16;
1703 case GL_INTENSITY32F_ARB:
1704 return &_mesa_texformat_intensity_float32;
1705 case GL_RGB16F_ARB:
1706 return &_mesa_texformat_rgba_float16;
1707 case GL_RGB32F_ARB:
1708 return &_mesa_texformat_rgba_float32;
1709 case GL_RGBA16F_ARB:
1710 return &_mesa_texformat_rgba_float16;
1711 case GL_RGBA32F_ARB:
1712 return &_mesa_texformat_rgba_float32;
1713
1714 case GL_DEPTH_COMPONENT:
1715 case GL_DEPTH_COMPONENT16:
1716 case GL_DEPTH_COMPONENT24:
1717 case GL_DEPTH_COMPONENT32:
1718 #if 0
1719 switch (type) {
1720 case GL_UNSIGNED_BYTE:
1721 case GL_UNSIGNED_SHORT:
1722 return &_mesa_texformat_z16;
1723 case GL_UNSIGNED_INT:
1724 return &_mesa_texformat_z32;
1725 case GL_UNSIGNED_INT_24_8_EXT:
1726 default:
1727 return &_mesa_texformat_z24_s8;
1728 }
1729 #else
1730 return &_mesa_texformat_z16;
1731 #endif
1732
1733 default:
1734 _mesa_problem(ctx,
1735 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
1736 (int)internalFormat);
1737 return NULL;
1738 }
1739
1740 return NULL; /* never get here */
1741 }
1742
1743 /**
1744 * All glTexImage calls go through this function.
1745 */
1746 static void radeon_teximage(
1747 GLcontext *ctx, int dims,
1748 GLint face, GLint level,
1749 GLint internalFormat,
1750 GLint width, GLint height, GLint depth,
1751 GLsizei imageSize,
1752 GLenum format, GLenum type, const GLvoid * pixels,
1753 const struct gl_pixelstore_attrib *packing,
1754 struct gl_texture_object *texObj,
1755 struct gl_texture_image *texImage,
1756 int compressed)
1757 {
1758 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1759 radeonTexObj* t = radeon_tex_obj(texObj);
1760 radeon_texture_image* image = get_radeon_texture_image(texImage);
1761
1762 rmesa->vtbl.flush_vertices(rmesa);
1763
1764 t->validated = GL_FALSE;
1765
1766 /* Choose and fill in the texture format for this image */
1767 texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
1768 _mesa_set_fetch_functions(texImage, dims);
1769
1770 if (texImage->TexFormat->TexelBytes == 0) {
1771 texImage->IsCompressed = GL_TRUE;
1772 texImage->CompressedSize =
1773 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
1774 texImage->Height, texImage->Depth,
1775 texImage->TexFormat->MesaFormat);
1776 } else {
1777 texImage->IsCompressed = GL_FALSE;
1778 texImage->CompressedSize = 0;
1779 }
1780
1781 /* Allocate memory for image */
1782 radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
1783
1784 if (!t->mt)
1785 radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
1786 if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
1787 image->mt = t->mt;
1788 image->mtlevel = level - t->mt->firstLevel;
1789 image->mtface = face;
1790 radeon_miptree_reference(t->mt);
1791 } else {
1792 int size;
1793 if (texImage->IsCompressed) {
1794 size = texImage->CompressedSize;
1795 } else {
1796 size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
1797 }
1798 texImage->Data = _mesa_alloc_texmemory(size);
1799 }
1800
1801 /* Upload texture image; note that the spec allows pixels to be NULL */
1802 if (compressed) {
1803 pixels = _mesa_validate_pbo_compressed_teximage(
1804 ctx, imageSize, pixels, packing, "glCompressedTexImage");
1805 } else {
1806 pixels = _mesa_validate_pbo_teximage(
1807 ctx, dims, width, height, depth,
1808 format, type, pixels, packing, "glTexImage");
1809 }
1810
1811 if (pixels) {
1812 radeon_teximage_map(image, GL_TRUE);
1813
1814 if (compressed) {
1815 memcpy(texImage->Data, pixels, imageSize);
1816 } else {
1817 GLuint dstRowStride;
1818 if (image->mt) {
1819 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
1820 dstRowStride = lvl->rowstride;
1821 } else {
1822 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
1823 }
1824 if (!texImage->TexFormat->StoreImage(ctx, dims,
1825 texImage->_BaseFormat,
1826 texImage->TexFormat,
1827 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
1828 dstRowStride,
1829 texImage->ImageOffsets,
1830 width, height, depth,
1831 format, type, pixels, packing))
1832 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1833 }
1834
1835 }
1836
1837 /* SGIS_generate_mipmap */
1838 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1839 radeon_generate_mipmap(ctx, texObj->Target, texObj);
1840 }
1841 radeon_teximage_unmap(image);
1842
1843 _mesa_unmap_teximage_pbo(ctx, packing);
1844
1845
1846 }
1847
1848 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
1849 GLint internalFormat,
1850 GLint width, GLint border,
1851 GLenum format, GLenum type, const GLvoid * pixels,
1852 const struct gl_pixelstore_attrib *packing,
1853 struct gl_texture_object *texObj,
1854 struct gl_texture_image *texImage)
1855 {
1856 radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
1857 0, format, type, pixels, packing, texObj, texImage, 0);
1858 }
1859
1860 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1861 GLint internalFormat,
1862 GLint width, GLint height, GLint border,
1863 GLenum format, GLenum type, const GLvoid * pixels,
1864 const struct gl_pixelstore_attrib *packing,
1865 struct gl_texture_object *texObj,
1866 struct gl_texture_image *texImage)
1867
1868 {
1869 GLuint face = radeon_face_for_target(target);
1870
1871 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
1872 0, format, type, pixels, packing, texObj, texImage, 0);
1873 }
1874
1875 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
1876 GLint level, GLint internalFormat,
1877 GLint width, GLint height, GLint border,
1878 GLsizei imageSize, const GLvoid * data,
1879 struct gl_texture_object *texObj,
1880 struct gl_texture_image *texImage)
1881 {
1882 GLuint face = radeon_face_for_target(target);
1883
1884 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
1885 imageSize, 0, 0, data, 0, texObj, texImage, 1);
1886 }
1887
1888 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
1889 GLint internalFormat,
1890 GLint width, GLint height, GLint depth,
1891 GLint border,
1892 GLenum format, GLenum type, const GLvoid * pixels,
1893 const struct gl_pixelstore_attrib *packing,
1894 struct gl_texture_object *texObj,
1895 struct gl_texture_image *texImage)
1896 {
1897 radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
1898 0, format, type, pixels, packing, texObj, texImage, 0);
1899 }
1900
1901 /**
1902 * Update a subregion of the given texture image.
1903 */
1904 static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
1905 GLint xoffset, GLint yoffset, GLint zoffset,
1906 GLsizei width, GLsizei height, GLsizei depth,
1907 GLenum format, GLenum type,
1908 const GLvoid * pixels,
1909 const struct gl_pixelstore_attrib *packing,
1910 struct gl_texture_object *texObj,
1911 struct gl_texture_image *texImage,
1912 int compressed)
1913 {
1914 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1915 radeonTexObj* t = radeon_tex_obj(texObj);
1916 radeon_texture_image* image = get_radeon_texture_image(texImage);
1917
1918 rmesa->vtbl.flush_vertices(rmesa);
1919
1920 t->validated = GL_FALSE;
1921 pixels = _mesa_validate_pbo_teximage(ctx, dims,
1922 width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
1923
1924 if (pixels) {
1925 GLint dstRowStride;
1926 radeon_teximage_map(image, GL_TRUE);
1927
1928 if (image->mt) {
1929 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
1930 dstRowStride = lvl->rowstride;
1931 } else {
1932 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
1933 }
1934
1935 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
1936 texImage->TexFormat, texImage->Data,
1937 xoffset, yoffset, zoffset,
1938 dstRowStride,
1939 texImage->ImageOffsets,
1940 width, height, depth,
1941 format, type, pixels, packing))
1942 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1943
1944
1945 }
1946
1947 /* GL_SGIS_generate_mipmap */
1948 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1949 radeon_generate_mipmap(ctx, texObj->Target, texObj);
1950 }
1951 radeon_teximage_unmap(image);
1952
1953 _mesa_unmap_teximage_pbo(ctx, packing);
1954
1955
1956 }
1957
1958 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
1959 GLint xoffset,
1960 GLsizei width,
1961 GLenum format, GLenum type,
1962 const GLvoid * pixels,
1963 const struct gl_pixelstore_attrib *packing,
1964 struct gl_texture_object *texObj,
1965 struct gl_texture_image *texImage)
1966 {
1967 radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
1968 format, type, pixels, packing, texObj, texImage, 0);
1969 }
1970
1971 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
1972 GLint xoffset, GLint yoffset,
1973 GLsizei width, GLsizei height,
1974 GLenum format, GLenum type,
1975 const GLvoid * pixels,
1976 const struct gl_pixelstore_attrib *packing,
1977 struct gl_texture_object *texObj,
1978 struct gl_texture_image *texImage)
1979 {
1980 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height,
1981 1, format, type, pixels, packing, texObj, texImage,
1982 0);
1983 }
1984
1985 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
1986 GLint level, GLint xoffset,
1987 GLint yoffset, GLsizei width,
1988 GLsizei height, GLenum format,
1989 GLsizei imageSize, const GLvoid * data,
1990 struct gl_texture_object *texObj,
1991 struct gl_texture_image *texImage)
1992 {
1993 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
1994 format, 0, data, 0, texObj, texImage, 1);
1995 }
1996
1997
1998 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1999 GLint xoffset, GLint yoffset, GLint zoffset,
2000 GLsizei width, GLsizei height, GLsizei depth,
2001 GLenum format, GLenum type,
2002 const GLvoid * pixels,
2003 const struct gl_pixelstore_attrib *packing,
2004 struct gl_texture_object *texObj,
2005 struct gl_texture_image *texImage)
2006 {
2007 radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
2008 format, type, pixels, packing, texObj, texImage, 0);
2009 }
2010
2011 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
2012 GLuint numrows, GLuint rowsize)
2013 {
2014 assert(rowsize <= dststride);
2015 assert(rowsize <= srcstride);
2016
2017 if (rowsize == srcstride && rowsize == dststride) {
2018 memcpy(dst, src, numrows*rowsize);
2019 } else {
2020 GLuint i;
2021 for(i = 0; i < numrows; ++i) {
2022 memcpy(dst, src, rowsize);
2023 dst += dststride;
2024 src += srcstride;
2025 }
2026 }
2027 }
2028
2029
2030 /**
2031 * Ensure that the given image is stored in the given miptree from now on.
2032 */
2033 static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
2034 {
2035 radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
2036 unsigned char *dest;
2037
2038 assert(image->mt != mt);
2039 assert(dstlvl->width == image->base.Width);
2040 assert(dstlvl->height == image->base.Height);
2041 assert(dstlvl->depth == image->base.Depth);
2042
2043 radeon_bo_map(mt->bo, GL_TRUE);
2044 dest = mt->bo->ptr + dstlvl->faces[face].offset;
2045
2046 if (image->mt) {
2047 /* Format etc. should match, so we really just need a memcpy().
2048 * In fact, that memcpy() could be done by the hardware in many
2049 * cases, provided that we have a proper memory manager.
2050 */
2051 radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
2052
2053 assert(srclvl->size == dstlvl->size);
2054 assert(srclvl->rowstride == dstlvl->rowstride);
2055
2056 radeon_bo_map(image->mt->bo, GL_FALSE);
2057 memcpy(dest,
2058 image->mt->bo->ptr + srclvl->faces[face].offset,
2059 dstlvl->size);
2060 radeon_bo_unmap(image->mt->bo);
2061
2062 radeon_miptree_unreference(image->mt);
2063 } else {
2064 uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
2065
2066 // if (mt->tilebits)
2067 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
2068
2069 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
2070 image->base.Height * image->base.Depth, srcrowstride);
2071
2072 _mesa_free_texmemory(image->base.Data);
2073 image->base.Data = 0;
2074 }
2075
2076 radeon_bo_unmap(mt->bo);
2077
2078 image->mt = mt;
2079 image->mtface = face;
2080 image->mtlevel = level;
2081 radeon_miptree_reference(image->mt);
2082 }
2083
2084 int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
2085 {
2086 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2087 radeonTexObj *t = radeon_tex_obj(texObj);
2088 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
2089 int face, level;
2090
2091 if (t->validated || t->image_override)
2092 return GL_TRUE;
2093
2094 if (RADEON_DEBUG & DEBUG_TEXTURE)
2095 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
2096
2097 if (baseimage->base.Border > 0)
2098 return GL_FALSE;
2099
2100 /* Ensure a matching miptree exists.
2101 *
2102 * Differing mipmap trees can result when the app uses TexImage to
2103 * change texture dimensions.
2104 *
2105 * Prefer to use base image's miptree if it
2106 * exists, since that most likely contains more valid data (remember
2107 * that the base level is usually significantly larger than the rest
2108 * of the miptree, so cubemaps are the only possible exception).
2109 */
2110 if (baseimage->mt &&
2111 baseimage->mt != t->mt &&
2112 radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
2113 radeon_miptree_unreference(t->mt);
2114 t->mt = baseimage->mt;
2115 radeon_miptree_reference(t->mt);
2116 } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
2117 radeon_miptree_unreference(t->mt);
2118 t->mt = 0;
2119 }
2120
2121 if (!t->mt) {
2122 if (RADEON_DEBUG & DEBUG_TEXTURE)
2123 fprintf(stderr, " Allocate new miptree\n");
2124 radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
2125 if (!t->mt) {
2126 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
2127 return GL_FALSE;
2128 }
2129 }
2130
2131 /* Ensure all images are stored in the single main miptree */
2132 for(face = 0; face < t->mt->faces; ++face) {
2133 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
2134 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
2135 if (RADEON_DEBUG & DEBUG_TEXTURE)
2136 fprintf(stderr, " face %i, level %i... ", face, level);
2137 if (t->mt == image->mt) {
2138 if (RADEON_DEBUG & DEBUG_TEXTURE)
2139 fprintf(stderr, "OK\n");
2140 continue;
2141 }
2142
2143 if (RADEON_DEBUG & DEBUG_TEXTURE)
2144 fprintf(stderr, "migrating\n");
2145 migrate_image_to_miptree(t->mt, image, face, level);
2146 }
2147 }
2148
2149 return GL_TRUE;
2150 }
2151
2152
2153 GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb,
2154 GLint x, GLint y)
2155 {
2156 GLubyte *ptr = rrb->bo->ptr;
2157 const __DRIdrawablePrivate *dPriv = rrb->dPriv;
2158 uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
2159 GLint offset;
2160 GLint nmacroblkpl;
2161 GLint nmicroblkpl;
2162
2163 x += dPriv->x;
2164 y += dPriv->y;
2165
2166 if (rrb->has_surface || !(rrb->bo->flags & mask)) {
2167 offset = x * rrb->cpp + y * rrb->pitch;
2168 } else {
2169 offset = 0;
2170 if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
2171 if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
2172 nmacroblkpl = rrb->pitch >> 5;
2173 offset += ((y >> 4) * nmacroblkpl) << 11;
2174 offset += ((y & 15) >> 1) << 8;
2175 offset += (y & 1) << 4;
2176 offset += (x >> 5) << 11;
2177 offset += ((x & 31) >> 2) << 5;
2178 offset += (x & 3) << 2;
2179 } else {
2180 nmacroblkpl = rrb->pitch >> 6;
2181 offset += ((y >> 3) * nmacroblkpl) << 11;
2182 offset += (y & 7) << 8;
2183 offset += (x >> 6) << 11;
2184 offset += ((x & 63) >> 3) << 5;
2185 offset += (x & 7) << 2;
2186 }
2187 } else {
2188 nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
2189 offset += (y * nmicroblkpl) << 5;
2190 offset += (x >> 3) << 5;
2191 offset += (x & 7) << 2;
2192 }
2193 }
2194 return &ptr[offset];
2195 }
2196
2197 GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb,
2198 GLint x, GLint y)
2199 {
2200 GLubyte *ptr = rrb->bo->ptr;
2201 const __DRIdrawablePrivate *dPriv = rrb->dPriv;
2202 uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
2203 GLint offset;
2204 GLint nmacroblkpl;
2205 GLint nmicroblkpl;
2206
2207 x += dPriv->x;
2208 y += dPriv->y;
2209
2210 if (rrb->has_surface || !(rrb->bo->flags & mask)) {
2211 offset = x * rrb->cpp + y * rrb->pitch;
2212 } else {
2213 offset = 0;
2214 if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
2215 if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
2216 nmacroblkpl = rrb->pitch >> 6;
2217 offset += ((y >> 4) * nmacroblkpl) << 11;
2218 offset += ((y & 15) >> 1) << 8;
2219 offset += (y & 1) << 4;
2220 offset += (x >> 6) << 11;
2221 offset += ((x & 63) >> 3) << 5;
2222 offset += (x & 7) << 1;
2223 } else {
2224 nmacroblkpl = rrb->pitch >> 7;
2225 offset += ((y >> 3) * nmacroblkpl) << 11;
2226 offset += (y & 7) << 8;
2227 offset += (x >> 7) << 11;
2228 offset += ((x & 127) >> 4) << 5;
2229 offset += (x & 15) << 2;
2230 }
2231 } else {
2232 nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
2233 offset += (y * nmicroblkpl) << 5;
2234 offset += (x >> 4) << 5;
2235 offset += (x & 15) << 2;
2236 }
2237 }
2238 return &ptr[offset];
2239 }
2240
2241 GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
2242 GLint x, GLint y)
2243 {
2244 GLubyte *ptr = rrb->bo->ptr;
2245 const __DRIdrawablePrivate *dPriv = rrb->dPriv;
2246 uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
2247 GLint offset;
2248 GLint microblkxs;
2249 GLint macroblkxs;
2250 GLint nmacroblkpl;
2251 GLint nmicroblkpl;
2252
2253 x += dPriv->x;
2254 y += dPriv->y;
2255
2256 if (rrb->has_surface || !(rrb->bo->flags & mask)) {
2257 offset = x * rrb->cpp + y * rrb->pitch;
2258 } else {
2259 offset = 0;
2260 if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
2261 if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
2262 microblkxs = 16 / rrb->cpp;
2263 macroblkxs = 128 / rrb->cpp;
2264 nmacroblkpl = rrb->pitch / macroblkxs;
2265 offset += ((y >> 4) * nmacroblkpl) << 11;
2266 offset += ((y & 15) >> 1) << 8;
2267 offset += (y & 1) << 4;
2268 offset += (x / macroblkxs) << 11;
2269 offset += ((x & (macroblkxs - 1)) / microblkxs) << 5;
2270 offset += (x & (microblkxs - 1)) * rrb->cpp;
2271 } else {
2272 microblkxs = 32 / rrb->cpp;
2273 macroblkxs = 256 / rrb->cpp;
2274 nmacroblkpl = rrb->pitch / macroblkxs;
2275 offset += ((y >> 3) * nmacroblkpl) << 11;
2276 offset += (y & 7) << 8;
2277 offset += (x / macroblkxs) << 11;
2278 offset += ((x & (macroblkxs - 1)) / microblkxs) << 5;
2279 offset += (x & (microblkxs - 1)) * rrb->cpp;
2280 }
2281 } else {
2282 microblkxs = 32 / rrb->cpp;
2283 nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
2284 offset += (y * nmicroblkpl) << 5;
2285 offset += (x / microblkxs) << 5;
2286 offset += (x & (microblkxs - 1)) * rrb->cpp;
2287 }
2288 }
2289 return &ptr[offset];
2290 }
2291
2292
2293 static void map_buffer(struct gl_renderbuffer *rb, GLboolean write)
2294 {
2295 struct radeon_renderbuffer *rrb = (void*)rb;
2296 int r;
2297
2298 if (rrb->bo) {
2299 r = radeon_bo_map(rrb->bo, write);
2300 if (r) {
2301 fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
2302 __FUNCTION__, r);
2303 }
2304 }
2305 }
2306
2307 static void unmap_buffer(struct gl_renderbuffer *rb)
2308 {
2309 struct radeon_renderbuffer *rrb = (void*)rb;
2310
2311 if (rrb->bo) {
2312 radeon_bo_unmap(rrb->bo);
2313 }
2314 }
2315
2316 void radeonSpanRenderStart(GLcontext * ctx)
2317 {
2318 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2319 int i;
2320
2321 rmesa->vtbl.flush_vertices(rmesa);
2322
2323 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
2324 if (ctx->Texture.Unit[i]._ReallyEnabled)
2325 ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
2326 }
2327
2328 /* color draw buffers */
2329 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
2330 map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE);
2331 }
2332
2333 map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE);
2334
2335 if (ctx->DrawBuffer->_DepthBuffer) {
2336 map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE);
2337 }
2338 if (ctx->DrawBuffer->_StencilBuffer)
2339 map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE);
2340
2341 /* The locking and wait for idle should really only be needed in classic mode.
2342 * In a future memory manager based implementation, this should become
2343 * unnecessary due to the fact that mapping our buffers, textures, etc.
2344 * should implicitly wait for any previous rendering commands that must
2345 * be waited on. */
2346 LOCK_HARDWARE(rmesa);
2347 radeonWaitForIdleLocked(rmesa);
2348 }
2349
2350 void radeonSpanRenderFinish(GLcontext * ctx)
2351 {
2352 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2353 int i;
2354 _swrast_flush(ctx);
2355 UNLOCK_HARDWARE(rmesa);
2356
2357 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
2358 if (ctx->Texture.Unit[i]._ReallyEnabled)
2359 ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
2360 }
2361
2362 /* color draw buffers */
2363 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
2364 unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
2365
2366 unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer);
2367
2368 if (ctx->DrawBuffer->_DepthBuffer)
2369 unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
2370 if (ctx->DrawBuffer->_StencilBuffer)
2371 unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
2372 }
2373
2374 void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
2375 {
2376 struct radeon_cs_space_check bos[1];
2377 int flushed, ret;
2378
2379 size = MAX2(size, MAX_DMA_BUF_SZ * 16);
2380
2381 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
2382 fprintf(stderr, "%s\n", __FUNCTION__);
2383
2384 if (rmesa->dma.flush) {
2385 radeon_bo_unmap(rmesa->dma.current);
2386 rmesa->dma.flush(rmesa->glCtx);
2387 }
2388
2389 if (rmesa->dma.nr_released_bufs > 4) {
2390 rcommonFlushCmdBuf(rmesa, __FUNCTION__);
2391 rmesa->dma.nr_released_bufs = 0;
2392 }
2393
2394 if (rmesa->dma.current) {
2395 radeon_bo_unref(rmesa->dma.current);
2396 rmesa->dma.current = 0;
2397 }
2398
2399 again_alloc:
2400 rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
2401 0, size, 4, RADEON_GEM_DOMAIN_GTT,
2402 0);
2403
2404 if (!rmesa->dma.current) {
2405 rcommonFlushCmdBuf(rmesa, __FUNCTION__);
2406 rmesa->dma.nr_released_bufs = 0;
2407 goto again_alloc;
2408 }
2409
2410 rmesa->dma.current_used = 0;
2411 rmesa->dma.current_vertexptr = 0;
2412
2413 bos[0].bo = rmesa->dma.current;
2414 bos[0].read_domains = RADEON_GEM_DOMAIN_GTT;
2415 bos[0].write_domain =0 ;
2416 bos[0].new_accounted = 0;
2417
2418 again:
2419 ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1);
2420 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
2421 fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen");
2422 assert(0);
2423 } else if (ret == RADEON_CS_SPACE_FLUSH) {
2424 rcommonFlushCmdBuf(rmesa, __FUNCTION__);
2425 if (flushed) {
2426 fprintf(stderr,"flushed but still no space\n");
2427 assert(0);
2428 }
2429 flushed = 1;
2430 goto again;
2431 }
2432
2433
2434 radeon_bo_map(rmesa->dma.current, 1);
2435 }
2436
2437 /* Allocates a region from rmesa->dma.current. If there isn't enough
2438 * space in current, grab a new buffer (and discard what was left of current)
2439 */
2440 void radeonAllocDmaRegion(radeonContextPtr rmesa,
2441 struct radeon_bo **pbo, int *poffset,
2442 int bytes, int alignment)
2443 {
2444 if (RADEON_DEBUG & DEBUG_IOCTL)
2445 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
2446
2447 if (rmesa->dma.flush)
2448 rmesa->dma.flush(rmesa->glCtx);
2449
2450 assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr);
2451
2452 alignment--;
2453 rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment;
2454
2455 if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size)
2456 radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15);
2457
2458 *poffset = rmesa->dma.current_used;
2459 *pbo = rmesa->dma.current;
2460 radeon_bo_ref(*pbo);
2461
2462 /* Always align to at least 16 bytes */
2463 rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15;
2464 rmesa->dma.current_vertexptr = rmesa->dma.current_used;
2465
2466 assert(rmesa->dma.current_used <= rmesa->dma.current->size);
2467 }
2468
2469 void radeonReleaseDmaRegion(radeonContextPtr rmesa)
2470 {
2471 if (rmesa->dma.current) {
2472 rmesa->dma.nr_released_bufs++;
2473 radeon_bo_unref(rmesa->dma.current);
2474 }
2475 rmesa->dma.current = NULL;
2476 }
2477
2478
2479 /* Flush vertices in the current dma region.
2480 */
2481 void rcommon_flush_last_swtcl_prim( GLcontext *ctx )
2482 {
2483 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2484 struct radeon_dma *dma = &rmesa->dma;
2485
2486
2487 if (RADEON_DEBUG & DEBUG_IOCTL)
2488 fprintf(stderr, "%s\n", __FUNCTION__);
2489 dma->flush = NULL;
2490
2491 if (dma->current) {
2492 GLuint current_offset = dma->current_used;
2493
2494 assert (dma->current_used +
2495 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
2496 dma->current_vertexptr);
2497
2498 radeon_bo_unmap(dma->current);
2499 if (dma->current_used != dma->current_vertexptr) {
2500 dma->current_used = dma->current_vertexptr;
2501
2502 rmesa->vtbl.swtcl_flush(ctx, current_offset);
2503 }
2504 radeonReleaseDmaRegion(rmesa);
2505 rmesa->swtcl.numverts = 0;
2506 }
2507 }
2508 /* Alloc space in the current dma region.
2509 */
2510 void *
2511 rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize )
2512 {
2513 GLuint bytes = vsize * nverts;
2514 void *head;
2515
2516 if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) {
2517 radeonRefillCurrentDmaRegion( rmesa, bytes);
2518 }
2519
2520 if (!rmesa->dma.flush) {
2521 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
2522 rmesa->dma.flush = rcommon_flush_last_swtcl_prim;
2523 }
2524
2525 ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
2526 ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim );
2527 ASSERT( rmesa->dma.current_used +
2528 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
2529 rmesa->dma.current_vertexptr );
2530
2531 // fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
2532 // rmesa->radeon.dma.current_vertexptr);
2533 head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr);
2534 rmesa->dma.current_vertexptr += bytes;
2535 rmesa->swtcl.numverts += nverts;
2536 return head;
2537 }