radeon: emit scissor when using cs path
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_common_context.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
6
7 The Weather Channel (TM) funded Tungsten Graphics to develop the
8 initial release of the Radeon 8500 driver under the XFree86 license.
9 This notice must be preserved.
10
11 All Rights Reserved.
12
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to
18 permit persons to whom the Software is furnished to do so, subject to
19 the following conditions:
20
21 The above copyright notice and this permission notice (including the
22 next paragraph) shall be included in all copies or substantial
23 portions of the Software.
24
25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
29 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
33 **************************************************************************/
34
35 #include "radeon_common.h"
36 #include "xmlpool.h" /* for symbolic values of enum-type options */
37 #include "utils.h"
38 #include "vblank.h"
39 #include "drirenderbuffer.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/state.h"
43 #include "main/simple_list.h"
44 #include "swrast/swrast.h"
45 #include "swrast_setup/swrast_setup.h"
46 #include "tnl/tnl.h"
47
48 #define DRIVER_DATE "20090101"
49
50 #ifndef RADEON_DEBUG
51 int RADEON_DEBUG = (0);
52 #endif
53
54 /* Return various strings for glGetString().
55 */
56 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
57 {
58 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
59 static char buffer[128];
60
61 switch (name) {
62 case GL_VENDOR:
63 if (IS_R300_CLASS(radeon->radeonScreen))
64 return (GLubyte *) "DRI R300 Project";
65 else
66 return (GLubyte *) "Tungsten Graphics, Inc.";
67
68 case GL_RENDERER:
69 {
70 unsigned offset;
71 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
72 radeon->radeonScreen->AGPMode;
73 const char* chipname;
74
75 if (IS_R300_CLASS(radeon->radeonScreen))
76 chipname = "R300";
77 else if (IS_R200_CLASS(radeon->radeonScreen))
78 chipname = "R200";
79 else
80 chipname = "R100";
81
82 offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
83 agp_mode);
84
85 if (IS_R300_CLASS(radeon->radeonScreen)) {
86 sprintf(&buffer[offset], " %sTCL",
87 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
88 ? "" : "NO-");
89 } else {
90 sprintf(&buffer[offset], " %sTCL",
91 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
92 ? "" : "NO-");
93 }
94
95 if (radeon->radeonScreen->driScreen->dri2.enabled)
96 strcat(buffer, " DRI2");
97
98 return (GLubyte *) buffer;
99 }
100
101 default:
102 return NULL;
103 }
104 }
105
106 /* Initialize the driver's misc functions.
107 */
108 static void radeonInitDriverFuncs(struct dd_function_table *functions)
109 {
110 functions->GetString = radeonGetString;
111 }
112
113 /**
114 * Create and initialize all common fields of the context,
115 * including the Mesa context itself.
116 */
117 GLboolean radeonInitContext(radeonContextPtr radeon,
118 struct dd_function_table* functions,
119 const __GLcontextModes * glVisual,
120 __DRIcontextPrivate * driContextPriv,
121 void *sharedContextPrivate)
122 {
123 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
124 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
125 GLcontext* ctx;
126 GLcontext* shareCtx;
127 int fthrottle_mode;
128
129 /* Fill in additional standard functions. */
130 radeonInitDriverFuncs(functions);
131
132 radeon->radeonScreen = screen;
133 /* Allocate and initialize the Mesa context */
134 if (sharedContextPrivate)
135 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
136 else
137 shareCtx = NULL;
138 radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
139 functions, (void *)radeon);
140 if (!radeon->glCtx)
141 return GL_FALSE;
142
143 ctx = radeon->glCtx;
144 driContextPriv->driverPrivate = radeon;
145
146 /* DRI fields */
147 radeon->dri.context = driContextPriv;
148 radeon->dri.screen = sPriv;
149 radeon->dri.drawable = NULL;
150 radeon->dri.readable = NULL;
151 radeon->dri.hwContext = driContextPriv->hHWContext;
152 radeon->dri.hwLock = &sPriv->pSAREA->lock;
153 radeon->dri.fd = sPriv->fd;
154 radeon->dri.drmMinor = sPriv->drm_version.minor;
155
156 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
157 screen->sarea_priv_offset);
158
159 /* Setup IRQs */
160 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
161 radeon->iw.irq_seq = -1;
162 radeon->irqsEmitted = 0;
163 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
164 radeon->radeonScreen->irq);
165
166 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
167
168 if (!radeon->do_irqs)
169 fprintf(stderr,
170 "IRQ's not enabled, falling back to %s: %d %d\n",
171 radeon->do_usleeps ? "usleeps" : "busy waits",
172 fthrottle_mode, radeon->radeonScreen->irq);
173
174 radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
175 "texture_depth");
176 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
177 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
178 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
179
180 return GL_TRUE;
181 }
182
183
184
185 /**
186 * Destroy the command buffer and state atoms.
187 */
188 static void radeon_destroy_atom_list(radeonContextPtr radeon)
189 {
190 struct radeon_state_atom *atom;
191
192 foreach(atom, &radeon->hw.atomlist) {
193 FREE(atom->cmd);
194 if (atom->lastcmd)
195 FREE(atom->lastcmd);
196 }
197
198 }
199
200 /**
201 * Cleanup common context fields.
202 * Called by r200DestroyContext/r300DestroyContext
203 */
204 void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
205 {
206 #ifdef RADEON_BO_TRACK
207 FILE *track;
208 #endif
209 GET_CURRENT_CONTEXT(ctx);
210 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
211 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
212
213 if (radeon == current) {
214 radeon_firevertices(radeon);
215 _mesa_make_current(NULL, NULL, NULL);
216 }
217
218 assert(radeon);
219 if (radeon) {
220
221 if (radeon->dma.current) {
222 rcommonFlushCmdBuf( radeon, __FUNCTION__ );
223 }
224
225 radeonReleaseArrays(radeon->glCtx, ~0);
226
227 if (radeon->vtbl.free_context)
228 radeon->vtbl.free_context(radeon->glCtx);
229 _swsetup_DestroyContext( radeon->glCtx );
230 _tnl_DestroyContext( radeon->glCtx );
231 _vbo_DestroyContext( radeon->glCtx );
232 _swrast_DestroyContext( radeon->glCtx );
233
234 radeonDestroyBuffer(radeon->dri.drawable);
235 radeonDestroyBuffer(radeon->dri.readable);
236
237 /* free atom list */
238 /* free the Mesa context */
239 _mesa_destroy_context(radeon->glCtx);
240
241 /* _mesa_destroy_context() might result in calls to functions that
242 * depend on the DriverCtx, so don't set it to NULL before.
243 *
244 * radeon->glCtx->DriverCtx = NULL;
245 */
246 /* free the option cache */
247 driDestroyOptionCache(&radeon->optionCache);
248
249 rcommonDestroyCmdBuf(radeon);
250
251 radeon_destroy_atom_list(radeon);
252
253 if (radeon->state.scissor.pClipRects) {
254 FREE(radeon->state.scissor.pClipRects);
255 radeon->state.scissor.pClipRects = 0;
256 }
257 }
258 #ifdef RADEON_BO_TRACK
259 track = fopen("/tmp/tracklog", "w");
260 if (track) {
261 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
262 fclose(track);
263 }
264 #endif
265 FREE(radeon);
266 }
267
268 /* Force the context `c' to be unbound from its buffer.
269 */
270 GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
271 {
272 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
273
274 if (RADEON_DEBUG & DEBUG_DRI)
275 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
276 radeon->glCtx);
277
278 return GL_TRUE;
279 }
280
281
282 static void
283 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
284 struct radeon_framebuffer *draw)
285 {
286 /* if radeon->fake */
287 struct radeon_renderbuffer *rb;
288
289 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
290 if (!rb->bo) {
291 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
292 radeon->radeonScreen->frontOffset,
293 0,
294 0,
295 RADEON_GEM_DOMAIN_VRAM,
296 0);
297 }
298 rb->cpp = radeon->radeonScreen->cpp;
299 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
300 }
301 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
302 if (!rb->bo) {
303 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
304 radeon->radeonScreen->backOffset,
305 0,
306 0,
307 RADEON_GEM_DOMAIN_VRAM,
308 0);
309 }
310 rb->cpp = radeon->radeonScreen->cpp;
311 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
312 }
313 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
314 if (!rb->bo) {
315 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
316 radeon->radeonScreen->depthOffset,
317 0,
318 0,
319 RADEON_GEM_DOMAIN_VRAM,
320 0);
321 }
322 rb->cpp = radeon->radeonScreen->cpp;
323 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
324 }
325 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
326 if (!rb->bo) {
327 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
328 radeon->radeonScreen->depthOffset,
329 0,
330 0,
331 RADEON_GEM_DOMAIN_VRAM,
332 0);
333 }
334 rb->cpp = radeon->radeonScreen->cpp;
335 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
336 }
337 }
338
339 static void
340 radeon_make_renderbuffer_current(radeonContextPtr radeon,
341 struct radeon_framebuffer *draw)
342 {
343 int size = 4096*4096*4;
344 /* if radeon->fake */
345 struct radeon_renderbuffer *rb;
346
347 if (radeon->radeonScreen->kernel_mm) {
348 radeon_make_kernel_renderbuffer_current(radeon, draw);
349 return;
350 }
351
352
353 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
354 if (!rb->bo) {
355 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
356 radeon->radeonScreen->frontOffset +
357 radeon->radeonScreen->fbLocation,
358 size,
359 4096,
360 RADEON_GEM_DOMAIN_VRAM,
361 0);
362 }
363 rb->cpp = radeon->radeonScreen->cpp;
364 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
365 }
366 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
367 if (!rb->bo) {
368 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
369 radeon->radeonScreen->backOffset +
370 radeon->radeonScreen->fbLocation,
371 size,
372 4096,
373 RADEON_GEM_DOMAIN_VRAM,
374 0);
375 }
376 rb->cpp = radeon->radeonScreen->cpp;
377 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
378 }
379 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
380 if (!rb->bo) {
381 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
382 radeon->radeonScreen->depthOffset +
383 radeon->radeonScreen->fbLocation,
384 size,
385 4096,
386 RADEON_GEM_DOMAIN_VRAM,
387 0);
388 }
389 rb->cpp = radeon->radeonScreen->cpp;
390 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
391 }
392 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
393 if (!rb->bo) {
394 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
395 radeon->radeonScreen->depthOffset +
396 radeon->radeonScreen->fbLocation,
397 size,
398 4096,
399 RADEON_GEM_DOMAIN_VRAM,
400 0);
401 }
402 rb->cpp = radeon->radeonScreen->cpp;
403 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
404 }
405 }
406
407
408 void
409 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
410 {
411 unsigned int attachments[10];
412 __DRIbuffer *buffers;
413 __DRIscreen *screen;
414 struct radeon_renderbuffer *rb;
415 int i, count;
416 struct radeon_framebuffer *draw;
417 radeonContextPtr radeon;
418 char *regname;
419 struct radeon_bo *depth_bo = NULL, *bo;
420
421 if (RADEON_DEBUG & DEBUG_DRI)
422 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
423
424 draw = drawable->driverPrivate;
425 screen = context->driScreenPriv;
426 radeon = (radeonContextPtr) context->driverPrivate;
427 i = 0;
428 if (draw->color_rb[0])
429 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
430 if (draw->color_rb[1])
431 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
432 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
433 attachments[i++] = __DRI_BUFFER_DEPTH;
434 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
435 attachments[i++] = __DRI_BUFFER_STENCIL;
436
437 buffers = (*screen->dri2.loader->getBuffers)(drawable,
438 &drawable->w,
439 &drawable->h,
440 attachments, i,
441 &count,
442 drawable->loaderPrivate);
443 if (buffers == NULL)
444 return;
445
446 /* set one cliprect to cover the whole drawable */
447 drawable->x = 0;
448 drawable->y = 0;
449 drawable->backX = 0;
450 drawable->backY = 0;
451 drawable->numClipRects = 1;
452 drawable->pClipRects[0].x1 = 0;
453 drawable->pClipRects[0].y1 = 0;
454 drawable->pClipRects[0].x2 = drawable->w;
455 drawable->pClipRects[0].y2 = drawable->h;
456 drawable->numBackClipRects = 1;
457 drawable->pBackClipRects[0].x1 = 0;
458 drawable->pBackClipRects[0].y1 = 0;
459 drawable->pBackClipRects[0].x2 = drawable->w;
460 drawable->pBackClipRects[0].y2 = drawable->h;
461 for (i = 0; i < count; i++) {
462 switch (buffers[i].attachment) {
463 case __DRI_BUFFER_FRONT_LEFT:
464 rb = draw->color_rb[0];
465 regname = "dri2 front buffer";
466 break;
467 case __DRI_BUFFER_BACK_LEFT:
468 rb = draw->color_rb[1];
469 regname = "dri2 back buffer";
470 break;
471 case __DRI_BUFFER_DEPTH:
472 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
473 regname = "dri2 depth buffer";
474 break;
475 case __DRI_BUFFER_STENCIL:
476 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
477 regname = "dri2 stencil buffer";
478 break;
479 case __DRI_BUFFER_ACCUM:
480 default:
481 fprintf(stderr,
482 "unhandled buffer attach event, attacment type %d\n",
483 buffers[i].attachment);
484 return;
485 }
486
487 if (rb == NULL)
488 continue;
489
490 if (rb->bo) {
491 uint32_t name = radeon_gem_name_bo(rb->bo);
492 if (name == buffers[i].name)
493 continue;
494 }
495
496 if (RADEON_DEBUG & DEBUG_DRI)
497 fprintf(stderr,
498 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
499 regname, buffers[i].name, buffers[i].attachment,
500 buffers[i].cpp, buffers[i].pitch);
501
502 rb->cpp = buffers[i].cpp;
503 rb->pitch = buffers[i].pitch;
504 rb->width = drawable->w;
505 rb->height = drawable->h;
506 rb->has_surface = 0;
507
508 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
509 if (RADEON_DEBUG & DEBUG_DRI)
510 fprintf(stderr, "(reusing depth buffer as stencil)\n");
511 bo = depth_bo;
512 radeon_bo_ref(bo);
513 } else {
514 bo = radeon_bo_open(radeon->radeonScreen->bom,
515 buffers[i].name,
516 0,
517 0,
518 RADEON_GEM_DOMAIN_VRAM,
519 buffers[i].flags);
520 if (bo == NULL) {
521
522 fprintf(stderr, "failed to attach %s %d\n",
523 regname, buffers[i].name);
524
525 }
526 }
527
528 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
529 if (draw->base.Visual.depthBits == 16)
530 rb->cpp = 2;
531 depth_bo = bo;
532 }
533
534 radeon_renderbuffer_set_bo(rb, bo);
535 radeon_bo_unref(bo);
536
537 }
538
539 driUpdateFramebufferSize(radeon->glCtx, drawable);
540 }
541
542 /* Force the context `c' to be the current context and associate with it
543 * buffer `b'.
544 */
545 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
546 __DRIdrawablePrivate * driDrawPriv,
547 __DRIdrawablePrivate * driReadPriv)
548 {
549 radeonContextPtr radeon;
550 struct radeon_framebuffer *drfb;
551 struct gl_framebuffer *readfb;
552
553 if (!driContextPriv) {
554 if (RADEON_DEBUG & DEBUG_DRI)
555 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
556 _mesa_make_current(NULL, NULL, NULL);
557 return GL_TRUE;
558 }
559
560 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
561 drfb = driDrawPriv->driverPrivate;
562 readfb = driReadPriv->driverPrivate;
563
564 if (driContextPriv->driScreenPriv->dri2.enabled) {
565 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
566 if (driDrawPriv != driReadPriv)
567 radeon_update_renderbuffers(driContextPriv, driReadPriv);
568 radeon->state.color.rrb =
569 radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT);
570 radeon->state.depth.rrb =
571 radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH);
572 } else {
573 radeon_make_renderbuffer_current(radeon, drfb);
574 }
575
576
577 if (RADEON_DEBUG & DEBUG_DRI)
578 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
579
580 if (radeon->dri.readable != driReadPriv)
581 radeon->dri.readable = driReadPriv;
582
583 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
584 if (driReadPriv != driDrawPriv)
585 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
586
587 _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
588
589 _mesa_update_state(radeon->glCtx);
590
591 if (radeon->glCtx->DrawBuffer == &drfb->base) {
592
593 if (radeon->dri.drawable != driDrawPriv) {
594 if (driDrawPriv->swap_interval == (unsigned)-1) {
595 int i;
596 driDrawPriv->vblFlags =
597 (radeon->radeonScreen->irq != 0)
598 ? driGetDefaultVBlankFlags(&radeon->
599 optionCache)
600 : VBLANK_FLAG_NO_IRQ;
601
602 driDrawableInitVBlank(driDrawPriv);
603 drfb->vbl_waited = driDrawPriv->vblSeq;
604
605 for (i = 0; i < 2; i++) {
606 if (drfb->color_rb[i])
607 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
608 }
609
610 }
611 radeon->dri.drawable = driDrawPriv;
612
613 radeon_window_moved(radeon);
614 }
615 radeon_draw_buffer(radeon->glCtx, &drfb->base);
616 }
617
618
619 if (RADEON_DEBUG & DEBUG_DRI)
620 fprintf(stderr, "End %s\n", __FUNCTION__);
621 return GL_TRUE;
622 }
623