• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <keithw@vmware.com>
34  */
35 
36 /*
37    - Scissor implementation
38    - buffer swap/copy ioctls
39    - finish/flush
40    - state emission
41    - cmdbuffer management
42 */
43 
44 #include <errno.h>
45 #include "main/glheader.h"
46 #include "main/imports.h"
47 #include "main/context.h"
48 #include "main/enums.h"
49 #include "main/fbobject.h"
50 #include "main/framebuffer.h"
51 #include "main/renderbuffer.h"
52 #include "drivers/common/meta.h"
53 
54 #include "radeon_common.h"
55 #include "radeon_drm.h"
56 #include "radeon_queryobj.h"
57 
58 /**
59  * Enable verbose debug output for emit code.
60  * 0 no output
61  * 1 most output
62  * 2 also print state alues
63  */
64 #define RADEON_CMDBUF         0
65 
66 /* =============================================================
67  * Scissoring
68  */
69 
70 /**
71  * Update cliprects and scissors.
72  */
radeonSetCliprects(radeonContextPtr radeon)73 void radeonSetCliprects(radeonContextPtr radeon)
74 {
75 	__DRIdrawable *const drawable = radeon_get_drawable(radeon);
76 	__DRIdrawable *const readable = radeon_get_readable(radeon);
77 
78 	if(drawable == NULL && readable == NULL)
79 		return;
80 
81 	struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate;
82 	struct radeon_framebuffer *const read_rfb = readable->driverPrivate;
83 
84 	if ((draw_rfb->base.Width != drawable->w) ||
85 	    (draw_rfb->base.Height != drawable->h)) {
86 		_mesa_resize_framebuffer(&radeon->glCtx, &draw_rfb->base,
87 					 drawable->w, drawable->h);
88 	}
89 
90 	if (drawable != readable) {
91 		if ((read_rfb->base.Width != readable->w) ||
92 		    (read_rfb->base.Height != readable->h)) {
93 			_mesa_resize_framebuffer(&radeon->glCtx, &read_rfb->base,
94 						 readable->w, readable->h);
95 		}
96 	}
97 
98 	if (radeon->state.scissor.enabled)
99 		radeonUpdateScissor(&radeon->glCtx);
100 
101 }
102 
103 
104 
radeonUpdateScissor(struct gl_context * ctx)105 void radeonUpdateScissor( struct gl_context *ctx )
106 {
107 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
108 	GLint x = ctx->Scissor.ScissorArray[0].X, y = ctx->Scissor.ScissorArray[0].Y;
109 	GLsizei w = ctx->Scissor.ScissorArray[0].Width, h = ctx->Scissor.ScissorArray[0].Height;
110 	int x1, y1, x2, y2;
111 	int min_x, min_y, max_x, max_y;
112 
113 	if (!ctx->DrawBuffer)
114 	    return;
115 	min_x = min_y = 0;
116 	max_x = ctx->DrawBuffer->Width - 1;
117 	max_y = ctx->DrawBuffer->Height - 1;
118 
119 	if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
120 		x1 = x;
121 		y1 = ctx->DrawBuffer->Height - (y + h);
122 		x2 = x + w - 1;
123 		y2 = y1 + h - 1;
124 	} else {
125 		x1 = x;
126 		y1 = y;
127 		x2 = x + w - 1;
128 		y2 = y + h - 1;
129 
130 	}
131 
132 	rmesa->state.scissor.rect.x1 = CLAMP(x1,  min_x, max_x);
133 	rmesa->state.scissor.rect.y1 = CLAMP(y1,  min_y, max_y);
134 	rmesa->state.scissor.rect.x2 = CLAMP(x2,  min_x, max_x);
135 	rmesa->state.scissor.rect.y2 = CLAMP(y2,  min_y, max_y);
136 
137 	if (rmesa->vtbl.update_scissor)
138 	   rmesa->vtbl.update_scissor(ctx);
139 }
140 
141 /* =============================================================
142  * Scissoring
143  */
144 
radeonScissor(struct gl_context * ctx)145 void radeonScissor(struct gl_context *ctx)
146 {
147 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
148 	if (ctx->Scissor.EnableFlags) {
149 		/* We don't pipeline cliprect changes */
150 		radeon_firevertices(radeon);
151 		radeonUpdateScissor(ctx);
152 	}
153 }
154 
155 /* ================================================================
156  * SwapBuffers with client-side throttling
157  */
158 
radeonGetAge(radeonContextPtr radeon)159 uint32_t radeonGetAge(radeonContextPtr radeon)
160 {
161 	drm_radeon_getparam_t gp;
162 	int ret;
163 	uint32_t age;
164 
165 	gp.param = RADEON_PARAM_LAST_CLEAR;
166 	gp.value = (int *)&age;
167 	ret = drmCommandWriteRead(radeon->radeonScreen->driScreen->fd, DRM_RADEON_GETPARAM,
168 				  &gp, sizeof(gp));
169 	if (ret) {
170 		fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __func__,
171 			ret);
172 		exit(1);
173 	}
174 
175 	return age;
176 }
177 
178 /**
179  * Check if we're about to draw into the front color buffer.
180  * If so, set the intel->front_buffer_dirty field to true.
181  */
182 void
radeon_check_front_buffer_rendering(struct gl_context * ctx)183 radeon_check_front_buffer_rendering(struct gl_context *ctx)
184 {
185 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
186 	const struct gl_framebuffer *fb = ctx->DrawBuffer;
187 
188 	if (fb->Name == 0) {
189 		/* drawing to window system buffer */
190 		if (fb->_NumColorDrawBuffers > 0) {
191 			if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
192 				radeon->front_buffer_dirty = GL_TRUE;
193 			}
194 		}
195 	}
196 }
197 
198 
radeon_draw_buffer(struct gl_context * ctx,struct gl_framebuffer * fb)199 void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
200 {
201 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
202 	struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL,
203 		*rrbColor = NULL;
204 	uint32_t offset = 0;
205 
206 
207 	if (!fb) {
208 		/* this can happen during the initial context initialization */
209 		return;
210 	}
211 
212 	/* radeons only handle 1 color draw so far */
213 	if (fb->_NumColorDrawBuffers != 1) {
214 		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
215 		return;
216 	}
217 
218 	/* Do this here, note core Mesa, since this function is called from
219 	 * many places within the driver.
220 	 */
221 	if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
222 		/* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
223 		_mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
224 		/* this updates the DrawBuffer's Width/Height if it's a FBO */
225 		_mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
226 	}
227 
228 	if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
229 		/* this may occur when we're called by glBindFrameBuffer() during
230 		 * the process of someone setting up renderbuffers, etc.
231 		 */
232 		/*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
233 		return;
234 	}
235 
236 	if (fb->Name) {
237 		;/* do something depthy/stencily TODO */
238         }
239 
240 		/* none */
241 	if (fb->Name == 0) {
242 		if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
243 			rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
244 			radeon->front_cliprects = GL_TRUE;
245 		} else {
246 			rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
247 			radeon->front_cliprects = GL_FALSE;
248 		}
249 	} else {
250 		/* user FBO in theory */
251 		struct radeon_renderbuffer *rrb;
252 		rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]);
253 		if (rrb) {
254 			offset = rrb->draw_offset;
255 			rrbColor = rrb;
256 		}
257 	}
258 
259 	if (rrbColor == NULL)
260 		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
261 	else
262 		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE);
263 
264 
265 	if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
266 		rrbDepth = radeon_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
267 		if (rrbDepth && rrbDepth->bo) {
268 			radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
269 		} else {
270 			radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE);
271 		}
272 	} else {
273 		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
274 		rrbDepth = NULL;
275 	}
276 
277 	if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
278 		rrbStencil = radeon_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
279 		if (rrbStencil && rrbStencil->bo) {
280 			radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
281 			/* need to re-compute stencil hw state */
282 			if (!rrbDepth)
283 				rrbDepth = rrbStencil;
284 		} else {
285 			radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE);
286 		}
287 	} else {
288 		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
289 		if (ctx->Driver.Enable != NULL)
290 			ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
291 		else
292 			ctx->NewState |= _NEW_STENCIL;
293 	}
294 
295 	/* Update culling direction which changes depending on the
296 	 * orientation of the buffer:
297 	 */
298 	if (ctx->Driver.FrontFace)
299 		ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
300 	else
301 		ctx->NewState |= _NEW_POLYGON;
302 
303 	/*
304 	 * Update depth test state
305 	 */
306 	if (ctx->Driver.Enable) {
307 		ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
308 				   (ctx->Depth.Test && fb->Visual.depthBits > 0));
309 		/* Need to update the derived ctx->Stencil._Enabled first */
310 		ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
311 				   (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0));
312 	} else {
313 		ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);
314 	}
315 
316 	_mesa_reference_renderbuffer(&radeon->state.depth.rb, &rrbDepth->base.Base);
317 	_mesa_reference_renderbuffer(&radeon->state.color.rb, &rrbColor->base.Base);
318 	radeon->state.color.draw_offset = offset;
319 
320 	ctx->NewState |= _NEW_VIEWPORT;
321 
322 	/* Set state we know depends on drawable parameters:
323 	 */
324 	radeonUpdateScissor(ctx);
325 	radeon->NewGLState |= _NEW_SCISSOR;
326 
327 	if (ctx->Driver.DepthRange)
328 		ctx->Driver.DepthRange(ctx);
329 
330 	/* Update culling direction which changes depending on the
331 	 * orientation of the buffer:
332 	 */
333 	if (ctx->Driver.FrontFace)
334 		ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
335 	else
336 		ctx->NewState |= _NEW_POLYGON;
337 }
338 
339 /**
340  * Called via glDrawBuffer.
341  */
radeonDrawBuffer(struct gl_context * ctx,GLenum mode)342 void radeonDrawBuffer( struct gl_context *ctx, GLenum mode )
343 {
344 	if (RADEON_DEBUG & RADEON_DRI)
345 		fprintf(stderr, "%s %s\n", __func__,
346 			_mesa_enum_to_string( mode ));
347 
348 	if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
349 		radeonContextPtr radeon = RADEON_CONTEXT(ctx);
350 
351 		const GLboolean was_front_buffer_rendering =
352 			radeon->is_front_buffer_rendering;
353 
354 		radeon->is_front_buffer_rendering = (mode == GL_FRONT_LEFT) ||
355                                             (mode == GL_FRONT);
356 
357       /* If we weren't front-buffer rendering before but we are now, make sure
358        * that the front-buffer has actually been allocated.
359        */
360 		if (!was_front_buffer_rendering && radeon->is_front_buffer_rendering) {
361 			radeon_update_renderbuffers(radeon->driContext,
362 				radeon->driContext->driDrawablePriv, GL_FALSE);
363       }
364 	}
365 
366 	radeon_draw_buffer(ctx, ctx->DrawBuffer);
367 }
368 
radeonReadBuffer(struct gl_context * ctx,GLenum mode)369 void radeonReadBuffer( struct gl_context *ctx, GLenum mode )
370 {
371 	if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
372 		struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
373 		const GLboolean was_front_buffer_reading = rmesa->is_front_buffer_reading;
374 		rmesa->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
375 					|| (mode == GL_FRONT);
376 
377 		if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) {
378 			radeon_update_renderbuffers(rmesa->driContext,
379 						    rmesa->driContext->driReadablePriv, GL_FALSE);
380 	 	}
381 	}
382 	/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
383 	if (ctx->ReadBuffer == ctx->DrawBuffer) {
384 		/* This will update FBO completeness status.
385 		 * A framebuffer will be incomplete if the GL_READ_BUFFER setting
386 		 * refers to a missing renderbuffer.  Calling glReadBuffer can set
387 		 * that straight and can make the drawing buffer complete.
388 		 */
389 		radeon_draw_buffer(ctx, ctx->DrawBuffer);
390 	}
391 }
392 
radeon_window_moved(radeonContextPtr radeon)393 void radeon_window_moved(radeonContextPtr radeon)
394 {
395 	/* Cliprects has to be updated before doing anything else */
396 	radeonSetCliprects(radeon);
397 }
398 
radeon_viewport(struct gl_context * ctx)399 void radeon_viewport(struct gl_context *ctx)
400 {
401 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
402 	__DRIcontext *driContext = radeon->driContext;
403 	void (*old_viewport)(struct gl_context *ctx);
404 
405 	if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
406 		if (radeon->is_front_buffer_rendering) {
407 			ctx->Driver.Flush(ctx);
408 		}
409 		radeon_update_renderbuffers(driContext, driContext->driDrawablePriv, GL_FALSE);
410 		if (driContext->driDrawablePriv != driContext->driReadablePriv)
411 			radeon_update_renderbuffers(driContext, driContext->driReadablePriv, GL_FALSE);
412 	}
413 
414 	old_viewport = ctx->Driver.Viewport;
415 	ctx->Driver.Viewport = NULL;
416 	radeon_window_moved(radeon);
417 	radeon_draw_buffer(ctx, radeon->glCtx.DrawBuffer);
418 	ctx->Driver.Viewport = old_viewport;
419 }
420 
radeon_print_state_atom(radeonContextPtr radeon,struct radeon_state_atom * state)421 static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state)
422 {
423 	int i, j, reg, count;
424 	int dwords;
425 	uint32_t packet0;
426 	if (!radeon_is_debug_enabled(RADEON_STATE, RADEON_VERBOSE) )
427 		return;
428 
429 	dwords = state->check(&radeon->glCtx, state);
430 
431 	fprintf(stderr, "  emit %s %d/%d\n", state->name, dwords, state->cmd_size);
432 
433 	if (state->cmd && radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) {
434 		if (dwords > state->cmd_size)
435 			dwords = state->cmd_size;
436 		for (i = 0; i < dwords;) {
437 			packet0 = state->cmd[i];
438 			reg = (packet0 & 0x1FFF) << 2;
439 			count = ((packet0 & 0x3FFF0000) >> 16) + 1;
440 			fprintf(stderr, "      %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n",
441 					state->name, i, reg, count);
442 			++i;
443 			for (j = 0; j < count && i < dwords; j++) {
444 				fprintf(stderr, "      %s[%d]: 0x%04x = %08x\n",
445 						state->name, i, reg, state->cmd[i]);
446 				reg += 4;
447 				++i;
448 			}
449 		}
450 	}
451 }
452 
453 /**
454  * Count total size for next state emit.
455  **/
radeonCountStateEmitSize(radeonContextPtr radeon)456 GLuint radeonCountStateEmitSize(radeonContextPtr radeon)
457 {
458 	struct radeon_state_atom *atom;
459 	GLuint dwords = 0;
460 	/* check if we are going to emit full state */
461 
462 	if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) {
463 		if (!radeon->hw.is_dirty)
464 			goto out;
465 		foreach(atom, &radeon->hw.atomlist) {
466 			if (atom->dirty) {
467 				const GLuint atom_size = atom->check(&radeon->glCtx, atom);
468 				dwords += atom_size;
469 				if (RADEON_CMDBUF && atom_size) {
470 					radeon_print_state_atom(radeon, atom);
471 				}
472 			}
473 		}
474 	} else {
475 		foreach(atom, &radeon->hw.atomlist) {
476 			const GLuint atom_size = atom->check(&radeon->glCtx, atom);
477 			dwords += atom_size;
478 			if (RADEON_CMDBUF && atom_size) {
479 				radeon_print_state_atom(radeon, atom);
480 			}
481 
482 		}
483 	}
484 out:
485 	radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %u\n", __func__, dwords);
486 	return dwords;
487 }
488 
radeon_emit_atom(radeonContextPtr radeon,struct radeon_state_atom * atom)489 static inline void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state_atom *atom)
490 {
491 	BATCH_LOCALS(radeon);
492 	int dwords;
493 
494 	dwords = atom->check(&radeon->glCtx, atom);
495 	if (dwords) {
496 
497 		radeon_print_state_atom(radeon, atom);
498 
499 		if (atom->emit) {
500 			atom->emit(&radeon->glCtx, atom);
501 		} else {
502 			BEGIN_BATCH(dwords);
503 			OUT_BATCH_TABLE(atom->cmd, dwords);
504 			END_BATCH();
505 		}
506 		atom->dirty = GL_FALSE;
507 
508 	} else {
509 		radeon_print(RADEON_STATE, RADEON_VERBOSE, "  skip state %s\n", atom->name);
510 	}
511 
512 }
513 
radeonEmitAtoms(radeonContextPtr radeon,GLboolean emitAll)514 static inline void radeonEmitAtoms(radeonContextPtr radeon, GLboolean emitAll)
515 {
516 	struct radeon_state_atom *atom;
517 
518 	/* Emit actual atoms */
519 	if (radeon->hw.all_dirty || emitAll) {
520 		foreach(atom, &radeon->hw.atomlist)
521 			radeon_emit_atom( radeon, atom );
522 	} else {
523 		foreach(atom, &radeon->hw.atomlist) {
524 			if ( atom->dirty )
525 				radeon_emit_atom( radeon, atom );
526 		}
527 	}
528 
529 	COMMIT_BATCH();
530 }
531 
radeonEmitState(radeonContextPtr radeon)532 void radeonEmitState(radeonContextPtr radeon)
533 {
534 	radeon_print(RADEON_STATE, RADEON_NORMAL, "%s\n", __func__);
535 
536 	if (radeon->vtbl.pre_emit_state)
537 		radeon->vtbl.pre_emit_state(radeon);
538 
539 	/* this code used to return here but now it emits zbs */
540 	if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty)
541 		return;
542 
543 	if (!radeon->cmdbuf.cs->cdw) {
544 		if (RADEON_DEBUG & RADEON_STATE)
545 			fprintf(stderr, "Begin reemit state\n");
546 
547 		radeonEmitAtoms(radeon, GL_TRUE);
548 	} else {
549 
550 		if (RADEON_DEBUG & RADEON_STATE)
551 			fprintf(stderr, "Begin dirty state\n");
552 
553 		radeonEmitAtoms(radeon, GL_FALSE);
554 	}
555 
556 	radeon->hw.is_dirty = GL_FALSE;
557 	radeon->hw.all_dirty = GL_FALSE;
558 }
559 
560 
radeonFlush(struct gl_context * ctx)561 void radeonFlush(struct gl_context *ctx)
562 {
563 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
564 	if (RADEON_DEBUG & RADEON_IOCTL)
565 		fprintf(stderr, "%s %d\n", __func__, radeon->cmdbuf.cs->cdw);
566 
567 	/* okay if we have no cmds in the buffer &&
568 	   we have no DMA flush &&
569 	   we have no DMA buffer allocated.
570 	   then no point flushing anything at all.
571 	*/
572 	if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved))
573 		goto flush_front;
574 
575 	if (radeon->dma.flush)
576 		radeon->dma.flush( ctx );
577 
578 	if (radeon->cmdbuf.cs->cdw)
579 		rcommonFlushCmdBuf(radeon, __func__);
580 
581 flush_front:
582 	if (_mesa_is_winsys_fbo(ctx->DrawBuffer) && radeon->front_buffer_dirty) {
583 		__DRIscreen *const screen = radeon->radeonScreen->driScreen;
584 
585 		if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2)
586 			&& (screen->dri2.loader->flushFrontBuffer != NULL)) {
587 			__DRIdrawable * drawable = radeon_get_drawable(radeon);
588 
589 			/* We set the dirty bit in radeon_prepare_render() if we're
590 			 * front buffer rendering once we get there.
591 			 */
592 			radeon->front_buffer_dirty = GL_FALSE;
593 
594 			screen->dri2.loader->flushFrontBuffer(drawable, drawable->loaderPrivate);
595 		}
596 	}
597 }
598 
599 /* Make sure all commands have been sent to the hardware and have
600  * completed processing.
601  */
radeonFinish(struct gl_context * ctx)602 void radeonFinish(struct gl_context * ctx)
603 {
604 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
605 	struct gl_framebuffer *fb = ctx->DrawBuffer;
606 	struct radeon_renderbuffer *rrb;
607 	int i;
608 
609 	if (ctx->Driver.Flush)
610 		ctx->Driver.Flush(ctx); /* +r6/r7 */
611 
612 	for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
613 		struct radeon_renderbuffer *rrb;
614 		rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]);
615 		if (rrb && rrb->bo)
616 			radeon_bo_wait(rrb->bo);
617 	}
618 	rrb = radeon_get_depthbuffer(radeon);
619 	if (rrb && rrb->bo)
620 		radeon_bo_wait(rrb->bo);
621 }
622 
623 /* cmdbuffer */
624 /**
625  * Send the current command buffer via ioctl to the hardware.
626  */
rcommonFlushCmdBufLocked(radeonContextPtr rmesa,const char * caller)627 int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
628 {
629 	int ret = 0;
630 
631 	if (rmesa->cmdbuf.flushing) {
632 		fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n");
633 		exit(-1);
634 	}
635 	rmesa->cmdbuf.flushing = 1;
636 
637 	if (RADEON_DEBUG & RADEON_IOCTL) {
638 		fprintf(stderr, "%s from %s\n", __func__, caller);
639 	}
640 
641 	radeonEmitQueryEnd(&rmesa->glCtx);
642 
643 	if (rmesa->cmdbuf.cs->cdw) {
644 		ret = radeon_cs_emit(rmesa->cmdbuf.cs);
645 		rmesa->hw.all_dirty = GL_TRUE;
646 	}
647 	radeon_cs_erase(rmesa->cmdbuf.cs);
648 	rmesa->cmdbuf.flushing = 0;
649 
650 	if (!rmesa->vtbl.revalidate_all_buffers(&rmesa->glCtx))
651 		fprintf(stderr,"failed to revalidate buffers\n");
652 
653 	return ret;
654 }
655 
rcommonFlushCmdBuf(radeonContextPtr rmesa,const char * caller)656 int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
657 {
658 	int ret;
659 
660 	radeonReleaseDmaRegions(rmesa);
661 
662 	ret = rcommonFlushCmdBufLocked(rmesa, caller);
663 
664 	if (ret) {
665 		fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to "
666 				"parse or rejected command stream. See dmesg "
667 				"for more info.\n", ret);
668 		exit(ret);
669 	}
670 
671 	return ret;
672 }
673 
674 /**
675  * Make sure that enough space is available in the command buffer
676  * by flushing if necessary.
677  *
678  * \param dwords The number of dwords we need to be free on the command buffer
679  */
rcommonEnsureCmdBufSpace(radeonContextPtr rmesa,int dwords,const char * caller)680 GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
681 {
682    if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
683 	 || radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
684       /* If we try to flush empty buffer there is too big rendering operation. */
685       assert(rmesa->cmdbuf.cs->cdw);
686       rcommonFlushCmdBuf(rmesa, caller);
687       return GL_TRUE;
688    }
689    return GL_FALSE;
690 }
691 
rcommonInitCmdBuf(radeonContextPtr rmesa)692 void rcommonInitCmdBuf(radeonContextPtr rmesa)
693 {
694 	GLuint size;
695 	struct drm_radeon_gem_info mminfo = { 0 };
696 	int fd = rmesa->radeonScreen->driScreen->fd;
697 
698 	/* Initialize command buffer */
699 	size = 256 * driQueryOptioni(&rmesa->optionCache,
700 				     "command_buffer_size");
701 	if (size < 2 * rmesa->hw.max_state_size) {
702 		size = 2 * rmesa->hw.max_state_size + 65535;
703 	}
704 	if (size > 64 * 256)
705 		size = 64 * 256;
706 
707 	radeon_print(RADEON_CS, RADEON_VERBOSE,
708 			"sizeof(drm_r300_cmd_header_t)=%zd\n", sizeof(drm_r300_cmd_header_t));
709 	radeon_print(RADEON_CS, RADEON_VERBOSE,
710 			"sizeof(drm_radeon_cmd_buffer_t)=%zd\n", sizeof(drm_radeon_cmd_buffer_t));
711 	radeon_print(RADEON_CS, RADEON_VERBOSE,
712 			"Allocating %d bytes command buffer (max state is %d bytes)\n",
713 			size * 4, rmesa->hw.max_state_size * 4);
714 
715 	rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd);
716 	if (rmesa->cmdbuf.csm == NULL) {
717 		/* FIXME: fatal error */
718 		return;
719 	}
720 	rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
721 	assert(rmesa->cmdbuf.cs != NULL);
722 	rmesa->cmdbuf.size = size;
723 
724 	radeon_cs_space_set_flush(rmesa->cmdbuf.cs,
725 				  (void (*)(void *))rmesa->glCtx.Driver.Flush, &rmesa->glCtx);
726 
727 
728 	if (!drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
729 				 &mminfo, sizeof(mminfo))) {
730 		radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM,
731 				    mminfo.vram_visible);
732 		radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT,
733 				    mminfo.gart_size);
734 	}
735 }
736 
737 /**
738  * Destroy the command buffer
739  */
rcommonDestroyCmdBuf(radeonContextPtr rmesa)740 void rcommonDestroyCmdBuf(radeonContextPtr rmesa)
741 {
742 	radeon_cs_destroy(rmesa->cmdbuf.cs);
743 	radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm);
744 }
745 
rcommonBeginBatch(radeonContextPtr rmesa,int n,const char * file,const char * function,int line)746 void rcommonBeginBatch(radeonContextPtr rmesa, int n,
747 		       const char *file,
748 		       const char *function,
749 		       int line)
750 {
751 	radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line);
752 
753     radeon_print(RADEON_CS, RADEON_VERBOSE, "BEGIN_BATCH(%d) at %d, from %s:%i\n",
754                         n, rmesa->cmdbuf.cs->cdw, function, line);
755 
756 }
757 
radeonUserClear(struct gl_context * ctx,GLuint mask)758 void radeonUserClear(struct gl_context *ctx, GLuint mask)
759 {
760    _mesa_meta_Clear(ctx, mask);
761 }
762