Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 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 "drivers/common/meta.h" |
||
39 | #include "main/context.h" |
||
40 | #include "main/framebuffer.h" |
||
41 | #include "main/fbobject.h" |
||
42 | #include "main/renderbuffer.h" |
||
43 | #include "main/state.h" |
||
44 | #include "main/simple_list.h" |
||
45 | #include "swrast/swrast.h" |
||
46 | #include "swrast_setup/swrast_setup.h" |
||
47 | #include "tnl/tnl.h" |
||
48 | |||
49 | #ifndef RADEON_DEBUG |
||
50 | int RADEON_DEBUG = (0); |
||
51 | #endif |
||
52 | |||
53 | |||
54 | static const char* get_chip_family_name(int chip_family) |
||
55 | { |
||
56 | switch(chip_family) { |
||
57 | #if defined(RADEON_R100) |
||
58 | case CHIP_FAMILY_R100: return "R100"; |
||
59 | case CHIP_FAMILY_RV100: return "RV100"; |
||
60 | case CHIP_FAMILY_RS100: return "RS100"; |
||
61 | case CHIP_FAMILY_RV200: return "RV200"; |
||
62 | case CHIP_FAMILY_RS200: return "RS200"; |
||
63 | #elif defined(RADEON_R200) |
||
64 | case CHIP_FAMILY_R200: return "R200"; |
||
65 | case CHIP_FAMILY_RV250: return "RV250"; |
||
66 | case CHIP_FAMILY_RS300: return "RS300"; |
||
67 | case CHIP_FAMILY_RV280: return "RV280"; |
||
68 | #endif |
||
69 | default: return "unknown"; |
||
70 | } |
||
71 | } |
||
72 | |||
73 | |||
74 | /* Return various strings for glGetString(). |
||
75 | */ |
||
76 | static const GLubyte *radeonGetString(struct gl_context * ctx, GLenum name) |
||
77 | { |
||
78 | radeonContextPtr radeon = RADEON_CONTEXT(ctx); |
||
79 | static char buffer[128]; |
||
80 | |||
81 | switch (name) { |
||
82 | case GL_VENDOR: |
||
83 | return (GLubyte *) "Tungsten Graphics, Inc."; |
||
84 | |||
85 | case GL_RENDERER: |
||
86 | { |
||
87 | unsigned offset; |
||
88 | GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : |
||
89 | radeon->radeonScreen->AGPMode; |
||
90 | char hardwarename[32]; |
||
91 | |||
92 | sprintf(hardwarename, "%s (%s %04X)", |
||
93 | #if defined(RADEON_R100) |
||
94 | "R100", |
||
95 | #elif defined(RADEON_R200) |
||
96 | "R200", |
||
97 | #endif |
||
98 | get_chip_family_name(radeon->radeonScreen->chip_family), |
||
99 | radeon->radeonScreen->device_id); |
||
100 | |||
101 | offset = driGetRendererString(buffer, hardwarename, agp_mode); |
||
102 | |||
103 | sprintf(&buffer[offset], " %sTCL", |
||
104 | !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) |
||
105 | ? "" : "NO-"); |
||
106 | |||
107 | strcat(buffer, " DRI2"); |
||
108 | |||
109 | return (GLubyte *) buffer; |
||
110 | } |
||
111 | |||
112 | default: |
||
113 | return NULL; |
||
114 | } |
||
115 | } |
||
116 | |||
117 | /* Initialize the driver's misc functions. |
||
118 | */ |
||
119 | static void radeonInitDriverFuncs(struct dd_function_table *functions) |
||
120 | { |
||
121 | functions->GetString = radeonGetString; |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * Create and initialize all common fields of the context, |
||
126 | * including the Mesa context itself. |
||
127 | */ |
||
128 | GLboolean radeonInitContext(radeonContextPtr radeon, |
||
129 | struct dd_function_table* functions, |
||
130 | const struct gl_config * glVisual, |
||
131 | __DRIcontext * driContextPriv, |
||
132 | void *sharedContextPrivate) |
||
133 | { |
||
134 | __DRIscreen *sPriv = driContextPriv->driScreenPriv; |
||
135 | radeonScreenPtr screen = (radeonScreenPtr) (sPriv->driverPrivate); |
||
136 | struct gl_context* ctx; |
||
137 | struct gl_context* shareCtx; |
||
138 | int fthrottle_mode; |
||
139 | |||
140 | /* Fill in additional standard functions. */ |
||
141 | radeonInitDriverFuncs(functions); |
||
142 | |||
143 | radeon->radeonScreen = screen; |
||
144 | /* Allocate and initialize the Mesa context */ |
||
145 | if (sharedContextPrivate) |
||
146 | shareCtx = &((radeonContextPtr)sharedContextPrivate)->glCtx; |
||
147 | else |
||
148 | shareCtx = NULL; |
||
149 | |||
150 | if (!_mesa_initialize_context(&radeon->glCtx, API_OPENGL_COMPAT, |
||
151 | glVisual, shareCtx, |
||
152 | functions)) |
||
153 | return GL_FALSE; |
||
154 | |||
155 | ctx = &radeon->glCtx; |
||
156 | driContextPriv->driverPrivate = radeon; |
||
157 | |||
158 | _mesa_meta_init(ctx); |
||
159 | |||
160 | /* DRI fields */ |
||
161 | radeon->dri.context = driContextPriv; |
||
162 | radeon->dri.screen = sPriv; |
||
163 | radeon->dri.fd = sPriv->fd; |
||
164 | radeon->dri.drmMinor = sPriv->drm_version.minor; |
||
165 | |||
166 | /* Setup IRQs */ |
||
167 | fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); |
||
168 | radeon->iw.irq_seq = -1; |
||
169 | radeon->irqsEmitted = 0; |
||
170 | radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && |
||
171 | radeon->radeonScreen->irq); |
||
172 | |||
173 | radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); |
||
174 | |||
175 | if (!radeon->do_irqs) |
||
176 | fprintf(stderr, |
||
177 | "IRQ's not enabled, falling back to %s: %d %d\n", |
||
178 | radeon->do_usleeps ? "usleeps" : "busy waits", |
||
179 | fthrottle_mode, radeon->radeonScreen->irq); |
||
180 | |||
181 | radeon->texture_depth = driQueryOptioni (&radeon->optionCache, |
||
182 | "texture_depth"); |
||
183 | if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) |
||
184 | radeon->texture_depth = ( glVisual->rgbBits > 16 ) ? |
||
185 | DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; |
||
186 | |||
187 | radeon->texture_row_align = 32; |
||
188 | radeon->texture_rect_row_align = 64; |
||
189 | radeon->texture_compressed_row_align = 32; |
||
190 | |||
191 | radeon_init_dma(radeon); |
||
192 | |||
193 | return GL_TRUE; |
||
194 | } |
||
195 | |||
196 | |||
197 | |||
198 | /** |
||
199 | * Destroy the command buffer and state atoms. |
||
200 | */ |
||
201 | static void radeon_destroy_atom_list(radeonContextPtr radeon) |
||
202 | { |
||
203 | struct radeon_state_atom *atom; |
||
204 | |||
205 | foreach(atom, &radeon->hw.atomlist) { |
||
206 | free(atom->cmd); |
||
207 | free(atom->lastcmd); |
||
208 | } |
||
209 | |||
210 | } |
||
211 | |||
212 | /** |
||
213 | * Cleanup common context fields. |
||
214 | * Called by r200DestroyContext |
||
215 | */ |
||
216 | void radeonDestroyContext(__DRIcontext *driContextPriv ) |
||
217 | { |
||
218 | #ifdef RADEON_BO_TRACK |
||
219 | FILE *track; |
||
220 | #endif |
||
221 | GET_CURRENT_CONTEXT(ctx); |
||
222 | radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; |
||
223 | radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; |
||
224 | |||
225 | assert(radeon); |
||
226 | |||
227 | _mesa_meta_free(&radeon->glCtx); |
||
228 | |||
229 | if (radeon == current) { |
||
230 | _mesa_make_current(NULL, NULL, NULL); |
||
231 | } |
||
232 | |||
233 | radeon_firevertices(radeon); |
||
234 | if (!is_empty_list(&radeon->dma.reserved)) { |
||
235 | rcommonFlushCmdBuf( radeon, __FUNCTION__ ); |
||
236 | } |
||
237 | |||
238 | radeonFreeDmaRegions(radeon); |
||
239 | radeonReleaseArrays(&radeon->glCtx, ~0); |
||
240 | if (radeon->vtbl.free_context) |
||
241 | radeon->vtbl.free_context(&radeon->glCtx); |
||
242 | _swsetup_DestroyContext( &radeon->glCtx ); |
||
243 | _tnl_DestroyContext( &radeon->glCtx ); |
||
244 | _vbo_DestroyContext( &radeon->glCtx ); |
||
245 | _swrast_DestroyContext( &radeon->glCtx ); |
||
246 | |||
247 | /* free atom list */ |
||
248 | /* free the Mesa context data */ |
||
249 | _mesa_free_context_data(&radeon->glCtx); |
||
250 | |||
251 | /* free the option cache */ |
||
252 | driDestroyOptionCache(&radeon->optionCache); |
||
253 | |||
254 | rcommonDestroyCmdBuf(radeon); |
||
255 | |||
256 | radeon_destroy_atom_list(radeon); |
||
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(__DRIcontext * driContextPriv) |
||
271 | { |
||
272 | radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; |
||
273 | |||
274 | if (RADEON_DEBUG & RADEON_DRI) |
||
275 | fprintf(stderr, "%s ctx %p\n", __FUNCTION__, |
||
276 | &radeon->glCtx); |
||
277 | |||
278 | /* Unset current context and dispath table */ |
||
279 | _mesa_make_current(NULL, NULL, NULL); |
||
280 | |||
281 | return GL_TRUE; |
||
282 | } |
||
283 | |||
284 | |||
285 | static unsigned |
||
286 | radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) |
||
287 | { |
||
288 | return _mesa_get_format_bytes(rb->base.Base.Format) * 8; |
||
289 | } |
||
290 | |||
291 | /* |
||
292 | * Check if drawable has been invalidated by dri2InvalidateDrawable(). |
||
293 | * Update renderbuffers if so. This prevents a client from accessing |
||
294 | * a backbuffer that has a swap pending but not yet completed. |
||
295 | * |
||
296 | * See intel_prepare_render for equivalent code in intel driver. |
||
297 | * |
||
298 | */ |
||
299 | void radeon_prepare_render(radeonContextPtr radeon) |
||
300 | { |
||
301 | __DRIcontext *driContext = radeon->dri.context; |
||
302 | __DRIdrawable *drawable; |
||
303 | __DRIscreen *screen; |
||
304 | |||
305 | screen = driContext->driScreenPriv; |
||
306 | if (!screen->dri2.loader) |
||
307 | return; |
||
308 | |||
309 | drawable = driContext->driDrawablePriv; |
||
310 | if (drawable->dri2.stamp != driContext->dri2.draw_stamp) { |
||
311 | if (drawable->lastStamp != drawable->dri2.stamp) |
||
312 | radeon_update_renderbuffers(driContext, drawable, GL_FALSE); |
||
313 | |||
314 | /* Intel driver does the equivalent of this, no clue if it is needed:*/ |
||
315 | radeon_draw_buffer(&radeon->glCtx, radeon->glCtx.DrawBuffer); |
||
316 | |||
317 | driContext->dri2.draw_stamp = drawable->dri2.stamp; |
||
318 | } |
||
319 | |||
320 | drawable = driContext->driReadablePriv; |
||
321 | if (drawable->dri2.stamp != driContext->dri2.read_stamp) { |
||
322 | if (drawable->lastStamp != drawable->dri2.stamp) |
||
323 | radeon_update_renderbuffers(driContext, drawable, GL_FALSE); |
||
324 | driContext->dri2.read_stamp = drawable->dri2.stamp; |
||
325 | } |
||
326 | |||
327 | /* If we're currently rendering to the front buffer, the rendering |
||
328 | * that will happen next will probably dirty the front buffer. So |
||
329 | * mark it as dirty here. |
||
330 | */ |
||
331 | if (radeon->is_front_buffer_rendering) |
||
332 | radeon->front_buffer_dirty = GL_TRUE; |
||
333 | } |
||
334 | |||
335 | void |
||
336 | radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, |
||
337 | GLboolean front_only) |
||
338 | { |
||
339 | unsigned int attachments[10]; |
||
340 | __DRIbuffer *buffers = NULL; |
||
341 | __DRIscreen *screen; |
||
342 | struct radeon_renderbuffer *rb; |
||
343 | int i, count; |
||
344 | struct radeon_framebuffer *draw; |
||
345 | radeonContextPtr radeon; |
||
346 | char *regname; |
||
347 | struct radeon_bo *depth_bo = NULL, *bo; |
||
348 | |||
349 | if (RADEON_DEBUG & RADEON_DRI) |
||
350 | fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); |
||
351 | |||
352 | draw = drawable->driverPrivate; |
||
353 | screen = context->driScreenPriv; |
||
354 | radeon = (radeonContextPtr) context->driverPrivate; |
||
355 | |||
356 | /* Set this up front, so that in case our buffers get invalidated |
||
357 | * while we're getting new buffers, we don't clobber the stamp and |
||
358 | * thus ignore the invalidate. */ |
||
359 | drawable->lastStamp = drawable->dri2.stamp; |
||
360 | |||
361 | if (screen->dri2.loader |
||
362 | && (screen->dri2.loader->base.version > 2) |
||
363 | && (screen->dri2.loader->getBuffersWithFormat != NULL)) { |
||
364 | struct radeon_renderbuffer *depth_rb; |
||
365 | struct radeon_renderbuffer *stencil_rb; |
||
366 | |||
367 | i = 0; |
||
368 | if ((front_only || radeon->is_front_buffer_rendering || |
||
369 | radeon->is_front_buffer_reading || |
||
370 | !draw->color_rb[1]) |
||
371 | && draw->color_rb[0]) { |
||
372 | attachments[i++] = __DRI_BUFFER_FRONT_LEFT; |
||
373 | attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); |
||
374 | } |
||
375 | |||
376 | if (!front_only) { |
||
377 | if (draw->color_rb[1]) { |
||
378 | attachments[i++] = __DRI_BUFFER_BACK_LEFT; |
||
379 | attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]); |
||
380 | } |
||
381 | |||
382 | depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); |
||
383 | stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); |
||
384 | |||
385 | if ((depth_rb != NULL) && (stencil_rb != NULL)) { |
||
386 | attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; |
||
387 | attachments[i++] = radeon_bits_per_pixel(depth_rb); |
||
388 | } else if (depth_rb != NULL) { |
||
389 | attachments[i++] = __DRI_BUFFER_DEPTH; |
||
390 | attachments[i++] = radeon_bits_per_pixel(depth_rb); |
||
391 | } else if (stencil_rb != NULL) { |
||
392 | attachments[i++] = __DRI_BUFFER_STENCIL; |
||
393 | attachments[i++] = radeon_bits_per_pixel(stencil_rb); |
||
394 | } |
||
395 | } |
||
396 | |||
397 | buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable, |
||
398 | &drawable->w, |
||
399 | &drawable->h, |
||
400 | attachments, i / 2, |
||
401 | &count, |
||
402 | drawable->loaderPrivate); |
||
403 | } else if (screen->dri2.loader) { |
||
404 | i = 0; |
||
405 | if (draw->color_rb[0]) |
||
406 | attachments[i++] = __DRI_BUFFER_FRONT_LEFT; |
||
407 | if (!front_only) { |
||
408 | if (draw->color_rb[1]) |
||
409 | attachments[i++] = __DRI_BUFFER_BACK_LEFT; |
||
410 | if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) |
||
411 | attachments[i++] = __DRI_BUFFER_DEPTH; |
||
412 | if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) |
||
413 | attachments[i++] = __DRI_BUFFER_STENCIL; |
||
414 | } |
||
415 | |||
416 | buffers = (*screen->dri2.loader->getBuffers)(drawable, |
||
417 | &drawable->w, |
||
418 | &drawable->h, |
||
419 | attachments, i, |
||
420 | &count, |
||
421 | drawable->loaderPrivate); |
||
422 | } |
||
423 | |||
424 | if (buffers == NULL) |
||
425 | return; |
||
426 | |||
427 | for (i = 0; i < count; i++) { |
||
428 | switch (buffers[i].attachment) { |
||
429 | case __DRI_BUFFER_FRONT_LEFT: |
||
430 | rb = draw->color_rb[0]; |
||
431 | regname = "dri2 front buffer"; |
||
432 | break; |
||
433 | case __DRI_BUFFER_FAKE_FRONT_LEFT: |
||
434 | rb = draw->color_rb[0]; |
||
435 | regname = "dri2 fake front buffer"; |
||
436 | break; |
||
437 | case __DRI_BUFFER_BACK_LEFT: |
||
438 | rb = draw->color_rb[1]; |
||
439 | regname = "dri2 back buffer"; |
||
440 | break; |
||
441 | case __DRI_BUFFER_DEPTH: |
||
442 | rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); |
||
443 | regname = "dri2 depth buffer"; |
||
444 | break; |
||
445 | case __DRI_BUFFER_DEPTH_STENCIL: |
||
446 | rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); |
||
447 | regname = "dri2 depth / stencil buffer"; |
||
448 | break; |
||
449 | case __DRI_BUFFER_STENCIL: |
||
450 | rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); |
||
451 | regname = "dri2 stencil buffer"; |
||
452 | break; |
||
453 | case __DRI_BUFFER_ACCUM: |
||
454 | default: |
||
455 | fprintf(stderr, |
||
456 | "unhandled buffer attach event, attacment type %d\n", |
||
457 | buffers[i].attachment); |
||
458 | return; |
||
459 | } |
||
460 | |||
461 | if (rb == NULL) |
||
462 | continue; |
||
463 | |||
464 | if (rb->bo) { |
||
465 | uint32_t name = radeon_gem_name_bo(rb->bo); |
||
466 | if (name == buffers[i].name) |
||
467 | continue; |
||
468 | } |
||
469 | |||
470 | if (RADEON_DEBUG & RADEON_DRI) |
||
471 | fprintf(stderr, |
||
472 | "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", |
||
473 | regname, buffers[i].name, buffers[i].attachment, |
||
474 | buffers[i].cpp, buffers[i].pitch); |
||
475 | |||
476 | rb->cpp = buffers[i].cpp; |
||
477 | rb->pitch = buffers[i].pitch; |
||
478 | rb->base.Base.Width = drawable->w; |
||
479 | rb->base.Base.Height = drawable->h; |
||
480 | rb->has_surface = 0; |
||
481 | |||
482 | if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { |
||
483 | if (RADEON_DEBUG & RADEON_DRI) |
||
484 | fprintf(stderr, "(reusing depth buffer as stencil)\n"); |
||
485 | bo = depth_bo; |
||
486 | radeon_bo_ref(bo); |
||
487 | } else { |
||
488 | uint32_t tiling_flags = 0, pitch = 0; |
||
489 | int ret; |
||
490 | |||
491 | bo = radeon_bo_open(radeon->radeonScreen->bom, |
||
492 | buffers[i].name, |
||
493 | 0, |
||
494 | 0, |
||
495 | RADEON_GEM_DOMAIN_VRAM, |
||
496 | buffers[i].flags); |
||
497 | |||
498 | if (bo == NULL) { |
||
499 | fprintf(stderr, "failed to attach %s %d\n", |
||
500 | regname, buffers[i].name); |
||
501 | continue; |
||
502 | } |
||
503 | |||
504 | ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch); |
||
505 | if (ret) { |
||
506 | fprintf(stderr, |
||
507 | "failed to get tiling for %s %d\n", |
||
508 | regname, buffers[i].name); |
||
509 | radeon_bo_unref(bo); |
||
510 | bo = NULL; |
||
511 | continue; |
||
512 | } else { |
||
513 | if (tiling_flags & RADEON_TILING_MACRO) |
||
514 | bo->flags |= RADEON_BO_FLAGS_MACRO_TILE; |
||
515 | if (tiling_flags & RADEON_TILING_MICRO) |
||
516 | bo->flags |= RADEON_BO_FLAGS_MICRO_TILE; |
||
517 | } |
||
518 | } |
||
519 | |||
520 | if (buffers[i].attachment == __DRI_BUFFER_DEPTH) { |
||
521 | if (draw->base.Visual.depthBits == 16) |
||
522 | rb->cpp = 2; |
||
523 | depth_bo = bo; |
||
524 | } |
||
525 | |||
526 | radeon_renderbuffer_set_bo(rb, bo); |
||
527 | radeon_bo_unref(bo); |
||
528 | |||
529 | if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { |
||
530 | rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); |
||
531 | if (rb != NULL) { |
||
532 | struct radeon_bo *stencil_bo = NULL; |
||
533 | |||
534 | if (rb->bo) { |
||
535 | uint32_t name = radeon_gem_name_bo(rb->bo); |
||
536 | if (name == buffers[i].name) |
||
537 | continue; |
||
538 | } |
||
539 | |||
540 | stencil_bo = bo; |
||
541 | radeon_bo_ref(stencil_bo); |
||
542 | radeon_renderbuffer_set_bo(rb, stencil_bo); |
||
543 | radeon_bo_unref(stencil_bo); |
||
544 | } |
||
545 | } |
||
546 | } |
||
547 | |||
548 | driUpdateFramebufferSize(&radeon->glCtx, drawable); |
||
549 | } |
||
550 | |||
551 | /* Force the context `c' to be the current context and associate with it |
||
552 | * buffer `b'. |
||
553 | */ |
||
554 | GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, |
||
555 | __DRIdrawable * driDrawPriv, |
||
556 | __DRIdrawable * driReadPriv) |
||
557 | { |
||
558 | radeonContextPtr radeon; |
||
559 | GET_CURRENT_CONTEXT(curCtx); |
||
560 | struct gl_framebuffer *drfb, *readfb; |
||
561 | |||
562 | if (driContextPriv) |
||
563 | radeon = (radeonContextPtr)driContextPriv->driverPrivate; |
||
564 | else |
||
565 | radeon = NULL; |
||
566 | /* According to the glXMakeCurrent() man page: "Pending commands to |
||
567 | * the previous context, if any, are flushed before it is released." |
||
568 | * But only flush if we're actually changing contexts. |
||
569 | */ |
||
570 | |||
571 | if ((radeonContextPtr)curCtx && (radeonContextPtr)curCtx != radeon) { |
||
572 | _mesa_flush(curCtx); |
||
573 | } |
||
574 | |||
575 | if (!driContextPriv) { |
||
576 | if (RADEON_DEBUG & RADEON_DRI) |
||
577 | fprintf(stderr, "%s ctx is null\n", __FUNCTION__); |
||
578 | _mesa_make_current(NULL, NULL, NULL); |
||
579 | return GL_TRUE; |
||
580 | } |
||
581 | |||
582 | if(driDrawPriv == NULL && driReadPriv == NULL) { |
||
583 | drfb = _mesa_create_framebuffer(&radeon->glCtx.Visual); |
||
584 | readfb = drfb; |
||
585 | } |
||
586 | else { |
||
587 | drfb = driDrawPriv->driverPrivate; |
||
588 | readfb = driReadPriv->driverPrivate; |
||
589 | } |
||
590 | |||
591 | if(driDrawPriv) |
||
592 | radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE); |
||
593 | if (driDrawPriv != driReadPriv) |
||
594 | radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE); |
||
595 | _mesa_reference_renderbuffer(&radeon->state.color.rb, |
||
596 | &(radeon_get_renderbuffer(drfb, BUFFER_BACK_LEFT)->base.Base)); |
||
597 | _mesa_reference_renderbuffer(&radeon->state.depth.rb, |
||
598 | &(radeon_get_renderbuffer(drfb, BUFFER_DEPTH)->base.Base)); |
||
599 | |||
600 | if (RADEON_DEBUG & RADEON_DRI) |
||
601 | fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, &radeon->glCtx, drfb, readfb); |
||
602 | |||
603 | if(driDrawPriv) |
||
604 | driUpdateFramebufferSize(&radeon->glCtx, driDrawPriv); |
||
605 | if (driReadPriv != driDrawPriv) |
||
606 | driUpdateFramebufferSize(&radeon->glCtx, driReadPriv); |
||
607 | |||
608 | _mesa_make_current(&radeon->glCtx, drfb, readfb); |
||
609 | if (driDrawPriv == NULL && driReadPriv == NULL) |
||
610 | _mesa_reference_framebuffer(&drfb, NULL); |
||
611 | |||
612 | _mesa_update_state(&radeon->glCtx); |
||
613 | |||
614 | if (radeon->glCtx.DrawBuffer == drfb) { |
||
615 | if(driDrawPriv != NULL) { |
||
616 | radeon_window_moved(radeon); |
||
617 | } |
||
618 | |||
619 | radeon_draw_buffer(&radeon->glCtx, drfb); |
||
620 | } |
||
621 | |||
622 | |||
623 | if (RADEON_DEBUG & RADEON_DRI) |
||
624 | fprintf(stderr, "End %s\n", __FUNCTION__); |
||
625 | |||
626 | return GL_TRUE; |
||
627 | }> |
||
628 |