Merge remote branch 'main/master' into radeon-rewrite
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_ioctl.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 * Keith Whitwell <keith@tungstengraphics.com>
35 */
36
37 #include <sched.h>
38 #include <errno.h>
39
40 #include "main/attrib.h"
41 #include "main/enable.h"
42 #include "main/blend.h"
43 #include "main/bufferobj.h"
44 #include "main/buffers.h"
45 #include "main/depth.h"
46 #include "main/shaders.h"
47 #include "main/texstate.h"
48 #include "main/varray.h"
49 #include "glapi/dispatch.h"
50 #include "swrast/swrast.h"
51 #include "main/stencil.h"
52 #include "main/matrix.h"
53
54 #include "main/glheader.h"
55 #include "main/imports.h"
56 #include "main/simple_list.h"
57 #include "swrast/swrast.h"
58
59 #include "radeon_context.h"
60 #include "radeon_common.h"
61 #include "radeon_state.h"
62 #include "radeon_ioctl.h"
63 #include "radeon_tcl.h"
64 #include "radeon_sanity.h"
65
66 #define STANDALONE_MMIO
67 #include "radeon_macros.h" /* for INREG() */
68
69 #include "drirenderbuffer.h"
70 #include "vblank.h"
71
72 #define RADEON_TIMEOUT 512
73 #define RADEON_IDLE_RETRY 16
74
75
76 /* =============================================================
77 * Kernel command buffer handling
78 */
79
80 /* The state atoms will be emitted in the order they appear in the atom list,
81 * so this step is important.
82 */
83 void radeonSetUpAtomList( r100ContextPtr rmesa )
84 {
85 int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits;
86
87 make_empty_list(&rmesa->radeon.hw.atomlist);
88 rmesa->radeon.hw.atomlist.name = "atom-list";
89
90 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
91 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
92 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
93 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
94 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
95 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
96 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
97 for (i = 0; i < mtu; ++i) {
98 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
99 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
100 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
101 }
102 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
103 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
104 for (i = 0; i < 3 + mtu; ++i)
105 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
106 for (i = 0; i < 8; ++i)
107 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
108 for (i = 0; i < 6; ++i)
109 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
110 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
111 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
112 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
113 insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
114 }
115
116 /* Fire a section of the retained (indexed_verts) buffer as a regular
117 * primtive.
118 */
119 extern void radeonEmitVbufPrim( r100ContextPtr rmesa,
120 GLuint vertex_format,
121 GLuint primitive,
122 GLuint vertex_nr )
123 {
124 BATCH_LOCALS(&rmesa->radeon);
125
126 assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
127
128 radeonEmitState(&rmesa->radeon);
129
130 #if RADEON_OLD_PACKETS
131 BEGIN_BATCH(8);
132 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
133 if (!rmesa->radeon.radeonScreen->kernel_mm) {
134 OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
135 } else {
136 OUT_BATCH(rmesa->ioctl.vertex_offset);
137 }
138
139 OUT_BATCH(vertex_nr);
140 OUT_BATCH(vertex_format);
141 OUT_BATCH(primitive | RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
142 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
143 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
144 (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
145
146 if (rmesa->radeon.radeonScreen->kernel_mm) {
147 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
148 rmesa->ioctl.bo,
149 RADEON_GEM_DOMAIN_GTT,
150 0, 0);
151 }
152
153 END_BATCH();
154
155 #else
156 BEGIN_BATCH(4);
157 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF, 1);
158 OUT_BATCH(vertex_format);
159 OUT_BATCH(primitive |
160 RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
161 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
162 RADEON_CP_VC_CNTL_MAOS_ENABLE |
163 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
164 (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
165 END_BATCH();
166 #endif
167 }
168
169 void radeonFlushElts( GLcontext *ctx )
170 {
171 r100ContextPtr rmesa = R100_CONTEXT(ctx);
172 BATCH_LOCALS(&rmesa->radeon);
173 int nr;
174 uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
175 int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
176
177 if (RADEON_DEBUG & DEBUG_IOCTL)
178 fprintf(stderr, "%s\n", __FUNCTION__);
179
180 assert( rmesa->radeon.dma.flush == radeonFlushElts );
181 rmesa->radeon.dma.flush = NULL;
182
183 nr = rmesa->tcl.elt_used;
184
185 #if RADEON_OLD_PACKETS
186 if (rmesa->radeon.radeonScreen->kernel_mm) {
187 dwords -= 2;
188 }
189 #endif
190
191 #if RADEON_OLD_PACKETS
192 cmd[1] |= (dwords + 3) << 16;
193 cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
194 #else
195 cmd[1] |= (dwords + 2) << 16;
196 cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
197 #endif
198
199 rmesa->radeon.cmdbuf.cs->cdw += dwords;
200 rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
201
202 #if RADEON_OLD_PACKETS
203 if (rmesa->radeon.radeonScreen->kernel_mm) {
204 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
205 rmesa->ioctl.bo,
206 RADEON_GEM_DOMAIN_GTT,
207 0, 0);
208 }
209 #endif
210
211 END_BATCH();
212
213 if (RADEON_DEBUG & DEBUG_SYNC) {
214 fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
215 radeonFinish( rmesa->radeon.glCtx );
216 }
217
218 }
219
220 GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
221 GLuint vertex_format,
222 GLuint primitive,
223 GLuint min_nr )
224 {
225 GLushort *retval;
226 int align_min_nr;
227 BATCH_LOCALS(&rmesa->radeon);
228
229 if (RADEON_DEBUG & DEBUG_IOCTL)
230 fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
231
232 assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
233
234 radeonEmitState(&rmesa->radeon);
235
236 rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
237
238 /* round up min_nr to align the state */
239 align_min_nr = (min_nr + 1) & ~1;
240
241 #if RADEON_OLD_PACKETS
242 BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
243 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
244 if (!rmesa->radeon.radeonScreen->kernel_mm) {
245 OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
246 } else {
247 OUT_BATCH(rmesa->ioctl.vertex_offset);
248 }
249 OUT_BATCH(0xffff);
250 OUT_BATCH(vertex_format);
251 OUT_BATCH(primitive |
252 RADEON_CP_VC_CNTL_PRIM_WALK_IND |
253 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
254 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
255
256 #else
257 BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4);
258 OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0);
259 OUT_BATCH(vertex_format);
260 OUT_BATCH(primitive |
261 RADEON_CP_VC_CNTL_PRIM_WALK_IND |
262 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
263 RADEON_CP_VC_CNTL_MAOS_ENABLE |
264 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
265 #endif
266
267
268 rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw;
269 rmesa->tcl.elt_used = min_nr;
270
271 retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
272
273 if (RADEON_DEBUG & DEBUG_PRIMS)
274 fprintf(stderr, "%s: header prim %x \n",
275 __FUNCTION__, primitive);
276
277 assert(!rmesa->radeon.dma.flush);
278 rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
279 rmesa->radeon.dma.flush = radeonFlushElts;
280
281 return retval;
282 }
283
284 void radeonEmitVertexAOS( r100ContextPtr rmesa,
285 GLuint vertex_size,
286 struct radeon_bo *bo,
287 GLuint offset )
288 {
289 #if RADEON_OLD_PACKETS
290 rmesa->ioctl.vertex_offset = offset;
291 rmesa->ioctl.bo = bo;
292 #else
293 BATCH_LOCALS(&rmesa->radeon);
294
295 if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
296 fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
297 __FUNCTION__, vertex_size, offset);
298
299 BEGIN_BATCH(7);
300 OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, 2);
301 OUT_BATCH(1);
302 OUT_BATCH(vertex_size | (vertex_size << 8));
303 OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
304 END_BATCH();
305
306 #endif
307 }
308
309
310 void radeonEmitAOS( r100ContextPtr rmesa,
311 GLuint nr,
312 GLuint offset )
313 {
314 #if RADEON_OLD_PACKETS
315 assert( nr == 1 );
316 rmesa->ioctl.bo = rmesa->tcl.aos[0].bo;
317 rmesa->ioctl.vertex_offset =
318 (rmesa->tcl.aos[0].offset + offset * rmesa->tcl.aos[0].stride * 4);
319 #else
320 BATCH_LOCALS(&rmesa->radeon);
321 uint32_t voffset;
322 // int sz = AOS_BUFSZ(nr);
323 int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
324 int i;
325
326 if (RADEON_DEBUG & DEBUG_IOCTL)
327 fprintf(stderr, "%s\n", __FUNCTION__);
328
329 BEGIN_BATCH(sz+2+(nr * 2));
330 OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1);
331 OUT_BATCH(nr);
332
333 if (!rmesa->radeon.radeonScreen->kernel_mm) {
334 for (i = 0; i + 1 < nr; i += 2) {
335 OUT_BATCH((rmesa->tcl.aos[i].components << 0) |
336 (rmesa->tcl.aos[i].stride << 8) |
337 (rmesa->tcl.aos[i + 1].components << 16) |
338 (rmesa->tcl.aos[i + 1].stride << 24));
339
340 voffset = rmesa->tcl.aos[i + 0].offset +
341 offset * 4 * rmesa->tcl.aos[i + 0].stride;
342 OUT_BATCH_RELOC(voffset,
343 rmesa->tcl.aos[i].bo,
344 voffset,
345 RADEON_GEM_DOMAIN_GTT,
346 0, 0);
347 voffset = rmesa->tcl.aos[i + 1].offset +
348 offset * 4 * rmesa->tcl.aos[i + 1].stride;
349 OUT_BATCH_RELOC(voffset,
350 rmesa->tcl.aos[i+1].bo,
351 voffset,
352 RADEON_GEM_DOMAIN_GTT,
353 0, 0);
354 }
355
356 if (nr & 1) {
357 OUT_BATCH((rmesa->tcl.aos[nr - 1].components << 0) |
358 (rmesa->tcl.aos[nr - 1].stride << 8));
359 voffset = rmesa->tcl.aos[nr - 1].offset +
360 offset * 4 * rmesa->tcl.aos[nr - 1].stride;
361 OUT_BATCH_RELOC(voffset,
362 rmesa->tcl.aos[nr - 1].bo,
363 voffset,
364 RADEON_GEM_DOMAIN_GTT,
365 0, 0);
366 }
367 } else {
368 for (i = 0; i + 1 < nr; i += 2) {
369 OUT_BATCH((rmesa->tcl.aos[i].components << 0) |
370 (rmesa->tcl.aos[i].stride << 8) |
371 (rmesa->tcl.aos[i + 1].components << 16) |
372 (rmesa->tcl.aos[i + 1].stride << 24));
373
374 voffset = rmesa->tcl.aos[i + 0].offset +
375 offset * 4 * rmesa->tcl.aos[i + 0].stride;
376 OUT_BATCH(voffset);
377 voffset = rmesa->tcl.aos[i + 1].offset +
378 offset * 4 * rmesa->tcl.aos[i + 1].stride;
379 OUT_BATCH(voffset);
380 }
381
382 if (nr & 1) {
383 OUT_BATCH((rmesa->tcl.aos[nr - 1].components << 0) |
384 (rmesa->tcl.aos[nr - 1].stride << 8));
385 voffset = rmesa->tcl.aos[nr - 1].offset +
386 offset * 4 * rmesa->tcl.aos[nr - 1].stride;
387 OUT_BATCH(voffset);
388 }
389 for (i = 0; i + 1 < nr; i += 2) {
390 voffset = rmesa->tcl.aos[i + 0].offset +
391 offset * 4 * rmesa->tcl.aos[i + 0].stride;
392 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
393 rmesa->tcl.aos[i+0].bo,
394 RADEON_GEM_DOMAIN_GTT,
395 0, 0);
396 voffset = rmesa->tcl.aos[i + 1].offset +
397 offset * 4 * rmesa->tcl.aos[i + 1].stride;
398 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
399 rmesa->tcl.aos[i+1].bo,
400 RADEON_GEM_DOMAIN_GTT,
401 0, 0);
402 }
403 if (nr & 1) {
404 voffset = rmesa->tcl.aos[nr - 1].offset +
405 offset * 4 * rmesa->tcl.aos[nr - 1].stride;
406 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
407 rmesa->tcl.aos[nr-1].bo,
408 RADEON_GEM_DOMAIN_GTT,
409 0, 0);
410 }
411 }
412 END_BATCH();
413
414 #endif
415 }
416
417 /* ================================================================
418 * Buffer clear
419 */
420 #define RADEON_MAX_CLEARS 256
421
422
423
424 static void
425 r100_meta_set_passthrough_transform(r100ContextPtr r100)
426 {
427 GLcontext *ctx = r100->radeon.glCtx;
428
429 r100->meta.saved_vp_x = ctx->Viewport.X;
430 r100->meta.saved_vp_y = ctx->Viewport.Y;
431 r100->meta.saved_vp_width = ctx->Viewport.Width;
432 r100->meta.saved_vp_height = ctx->Viewport.Height;
433 r100->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
434
435 _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
436
437 _mesa_MatrixMode(GL_PROJECTION);
438 _mesa_PushMatrix();
439 _mesa_LoadIdentity();
440 _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
441
442 _mesa_MatrixMode(GL_MODELVIEW);
443 _mesa_PushMatrix();
444 _mesa_LoadIdentity();
445 }
446
447 static void
448 r100_meta_restore_transform(r100ContextPtr r100)
449 {
450 _mesa_MatrixMode(GL_PROJECTION);
451 _mesa_PopMatrix();
452 _mesa_MatrixMode(GL_MODELVIEW);
453 _mesa_PopMatrix();
454
455 _mesa_MatrixMode(r100->meta.saved_matrix_mode);
456
457 _mesa_Viewport(r100->meta.saved_vp_x, r100->meta.saved_vp_y,
458 r100->meta.saved_vp_width, r100->meta.saved_vp_height);
459 }
460
461 /**
462 * Perform glClear where mask contains only color, depth, and/or stencil.
463 *
464 * The implementation is based on calling into Mesa to set GL state and
465 * performing normal triangle rendering. The intent of this path is to
466 * have as generic a path as possible, so that any driver could make use of
467 * it.
468 */
469 static void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
470 {
471 r100ContextPtr rmesa = R100_CONTEXT(ctx);
472 GLfloat vertices[4][3];
473 GLfloat color[4][4];
474 GLfloat dst_z;
475 struct gl_framebuffer *fb = ctx->DrawBuffer;
476 int i;
477 GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
478 GLboolean saved_shader_program = 0;
479 unsigned int saved_active_texture;
480
481 assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT |
482 BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0);
483
484 _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
485 GL_CURRENT_BIT |
486 GL_DEPTH_BUFFER_BIT |
487 GL_ENABLE_BIT |
488 GL_STENCIL_BUFFER_BIT |
489 GL_TRANSFORM_BIT |
490 GL_CURRENT_BIT);
491 _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
492 saved_active_texture = ctx->Texture.CurrentUnit;
493
494 /* Disable existing GL state we don't want to apply to a clear. */
495 _mesa_Disable(GL_ALPHA_TEST);
496 _mesa_Disable(GL_BLEND);
497 _mesa_Disable(GL_CULL_FACE);
498 _mesa_Disable(GL_FOG);
499 _mesa_Disable(GL_POLYGON_SMOOTH);
500 _mesa_Disable(GL_POLYGON_STIPPLE);
501 _mesa_Disable(GL_POLYGON_OFFSET_FILL);
502 _mesa_Disable(GL_LIGHTING);
503 _mesa_Disable(GL_CLIP_PLANE0);
504 _mesa_Disable(GL_CLIP_PLANE1);
505 _mesa_Disable(GL_CLIP_PLANE2);
506 _mesa_Disable(GL_CLIP_PLANE3);
507 _mesa_Disable(GL_CLIP_PLANE4);
508 _mesa_Disable(GL_CLIP_PLANE5);
509 if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
510 saved_fp_enable = GL_TRUE;
511 _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
512 }
513 if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
514 saved_vp_enable = GL_TRUE;
515 _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
516 }
517 if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
518 saved_shader_program = ctx->Shader.CurrentProgram->Name;
519 _mesa_UseProgramObjectARB(0);
520 }
521
522 if (ctx->Texture._EnabledUnits != 0) {
523 int i;
524
525 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
526 _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
527 _mesa_Disable(GL_TEXTURE_1D);
528 _mesa_Disable(GL_TEXTURE_2D);
529 _mesa_Disable(GL_TEXTURE_3D);
530 if (ctx->Extensions.ARB_texture_cube_map)
531 _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
532 if (ctx->Extensions.NV_texture_rectangle)
533 _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
534 if (ctx->Extensions.MESA_texture_array) {
535 _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
536 _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
537 }
538 }
539 }
540
541 r100_meta_set_passthrough_transform(rmesa);
542
543 for (i = 0; i < 4; i++) {
544 color[i][0] = ctx->Color.ClearColor[0];
545 color[i][1] = ctx->Color.ClearColor[1];
546 color[i][2] = ctx->Color.ClearColor[2];
547 color[i][3] = ctx->Color.ClearColor[3];
548 }
549
550 /* convert clear Z from [0,1] to NDC coord in [-1,1] */
551 dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
552
553 /* Prepare the vertices, which are the same regardless of which buffer we're
554 * drawing to.
555 */
556 vertices[0][0] = fb->_Xmin;
557 vertices[0][1] = fb->_Ymin;
558 vertices[0][2] = dst_z;
559 vertices[1][0] = fb->_Xmax;
560 vertices[1][1] = fb->_Ymin;
561 vertices[1][2] = dst_z;
562 vertices[2][0] = fb->_Xmax;
563 vertices[2][1] = fb->_Ymax;
564 vertices[2][2] = dst_z;
565 vertices[3][0] = fb->_Xmin;
566 vertices[3][1] = fb->_Ymax;
567 vertices[3][2] = dst_z;
568
569 _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
570 _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
571 _mesa_Enable(GL_COLOR_ARRAY);
572 _mesa_Enable(GL_VERTEX_ARRAY);
573
574 while (mask != 0) {
575 GLuint this_mask = 0;
576
577 if (mask & BUFFER_BIT_BACK_LEFT)
578 this_mask = BUFFER_BIT_BACK_LEFT;
579 else if (mask & BUFFER_BIT_FRONT_LEFT)
580 this_mask = BUFFER_BIT_FRONT_LEFT;
581
582 /* Clear depth/stencil in the same pass as color. */
583 this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
584
585 /* Select the current color buffer and use the color write mask if
586 * we have one, otherwise don't write any color channels.
587 */
588 if (this_mask & BUFFER_BIT_FRONT_LEFT)
589 _mesa_DrawBuffer(GL_FRONT_LEFT);
590 else if (this_mask & BUFFER_BIT_BACK_LEFT)
591 _mesa_DrawBuffer(GL_BACK_LEFT);
592 else
593 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
594
595 /* Control writing of the depth clear value to depth. */
596 if (this_mask & BUFFER_BIT_DEPTH) {
597 _mesa_DepthFunc(GL_ALWAYS);
598 _mesa_Enable(GL_DEPTH_TEST);
599 } else {
600 _mesa_Disable(GL_DEPTH_TEST);
601 _mesa_DepthMask(GL_FALSE);
602 }
603
604 /* Control writing of the stencil clear value to stencil. */
605 if (this_mask & BUFFER_BIT_STENCIL) {
606 _mesa_Enable(GL_STENCIL_TEST);
607 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
608 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
609 ctx->Stencil.WriteMask[0]);
610 } else {
611 _mesa_Disable(GL_STENCIL_TEST);
612 }
613
614 CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
615
616 mask &= ~this_mask;
617 }
618
619 r100_meta_restore_transform(rmesa);
620
621 _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
622 if (saved_fp_enable)
623 _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
624 if (saved_vp_enable)
625 _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
626
627 if (saved_shader_program)
628 _mesa_UseProgramObjectARB(saved_shader_program);
629
630 _mesa_PopClientAttrib();
631 _mesa_PopAttrib();
632 }
633
634 static void radeonUserClear(GLcontext *ctx, GLuint mask)
635 {
636 radeon_clear_tris(ctx, mask);
637 }
638
639 static void radeonKernelClear(GLcontext *ctx, GLuint flags)
640 {
641 r100ContextPtr rmesa = R100_CONTEXT(ctx);
642 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
643 drm_radeon_sarea_t *sarea = rmesa->radeon.sarea;
644 uint32_t clear;
645 GLint ret, i;
646 GLint cx, cy, cw, ch;
647
648 LOCK_HARDWARE( &rmesa->radeon );
649
650 /* compute region after locking: */
651 cx = ctx->DrawBuffer->_Xmin;
652 cy = ctx->DrawBuffer->_Ymin;
653 cw = ctx->DrawBuffer->_Xmax - cx;
654 ch = ctx->DrawBuffer->_Ymax - cy;
655
656 /* Flip top to bottom */
657 cx += dPriv->x;
658 cy = dPriv->y + dPriv->h - cy - ch;
659
660 /* Throttle the number of clear ioctls we do.
661 */
662 while ( 1 ) {
663 int ret;
664 drm_radeon_getparam_t gp;
665
666 gp.param = RADEON_PARAM_LAST_CLEAR;
667 gp.value = (int *)&clear;
668 ret = drmCommandWriteRead( rmesa->radeon.dri.fd,
669 DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
670
671 if ( ret ) {
672 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
673 exit(1);
674 }
675
676 if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
677 break;
678 }
679
680 if ( rmesa->radeon.do_usleeps ) {
681 UNLOCK_HARDWARE( &rmesa->radeon );
682 DO_USLEEP( 1 );
683 LOCK_HARDWARE( &rmesa->radeon );
684 }
685 }
686
687 /* Send current state to the hardware */
688 rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ );
689
690 for ( i = 0 ; i < dPriv->numClipRects ; ) {
691 GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
692 drm_clip_rect_t *box = dPriv->pClipRects;
693 drm_clip_rect_t *b = rmesa->radeon.sarea->boxes;
694 drm_radeon_clear_t clear;
695 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
696 GLint n = 0;
697
698 if (cw != dPriv->w || ch != dPriv->h) {
699 /* clear subregion */
700 for ( ; i < nr ; i++ ) {
701 GLint x = box[i].x1;
702 GLint y = box[i].y1;
703 GLint w = box[i].x2 - x;
704 GLint h = box[i].y2 - y;
705
706 if ( x < cx ) w -= cx - x, x = cx;
707 if ( y < cy ) h -= cy - y, y = cy;
708 if ( x + w > cx + cw ) w = cx + cw - x;
709 if ( y + h > cy + ch ) h = cy + ch - y;
710 if ( w <= 0 ) continue;
711 if ( h <= 0 ) continue;
712
713 b->x1 = x;
714 b->y1 = y;
715 b->x2 = x + w;
716 b->y2 = y + h;
717 b++;
718 n++;
719 }
720 } else {
721 /* clear whole buffer */
722 for ( ; i < nr ; i++ ) {
723 *b++ = box[i];
724 n++;
725 }
726 }
727
728 rmesa->radeon.sarea->nbox = n;
729
730 clear.flags = flags;
731 clear.clear_color = rmesa->radeon.state.color.clear;
732 clear.clear_depth = rmesa->radeon.state.depth.clear;
733 clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
734 clear.depth_mask = rmesa->radeon.state.stencil.clear;
735 clear.depth_boxes = depth_boxes;
736
737 n--;
738 b = rmesa->radeon.sarea->boxes;
739 for ( ; n >= 0 ; n-- ) {
740 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1;
741 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1;
742 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2;
743 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2;
744 depth_boxes[n].f[CLEAR_DEPTH] =
745 (float)rmesa->radeon.state.depth.clear;
746 }
747
748 ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR,
749 &clear, sizeof(drm_radeon_clear_t));
750
751 if ( ret ) {
752 UNLOCK_HARDWARE( &rmesa->radeon );
753 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
754 exit( 1 );
755 }
756 }
757 UNLOCK_HARDWARE( &rmesa->radeon );
758 }
759
760 static void radeonClear( GLcontext *ctx, GLbitfield mask )
761 {
762 r100ContextPtr rmesa = R100_CONTEXT(ctx);
763 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
764 GLuint flags = 0;
765 GLuint color_mask = 0;
766 GLuint orig_mask = mask;
767
768 if ( RADEON_DEBUG & DEBUG_IOCTL ) {
769 fprintf( stderr, "radeonClear\n");
770 }
771
772 {
773 LOCK_HARDWARE( &rmesa->radeon );
774 UNLOCK_HARDWARE( &rmesa->radeon );
775 if ( dPriv->numClipRects == 0 )
776 return;
777 }
778
779 radeon_firevertices(&rmesa->radeon);
780
781 if ( mask & BUFFER_BIT_FRONT_LEFT ) {
782 flags |= RADEON_FRONT;
783 color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
784 mask &= ~BUFFER_BIT_FRONT_LEFT;
785 }
786
787 if ( mask & BUFFER_BIT_BACK_LEFT ) {
788 flags |= RADEON_BACK;
789 color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
790 mask &= ~BUFFER_BIT_BACK_LEFT;
791 }
792
793 if ( mask & BUFFER_BIT_DEPTH ) {
794 flags |= RADEON_DEPTH;
795 mask &= ~BUFFER_BIT_DEPTH;
796 }
797
798 if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) {
799 flags |= RADEON_STENCIL;
800 mask &= ~BUFFER_BIT_STENCIL;
801 }
802
803 if ( mask ) {
804 if (RADEON_DEBUG & DEBUG_FALLBACKS)
805 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
806 _swrast_Clear( ctx, mask );
807 }
808
809 if ( !flags )
810 return;
811
812 if (rmesa->using_hyperz) {
813 flags |= RADEON_USE_COMP_ZBUF;
814 /* if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)
815 flags |= RADEON_USE_HIERZ; */
816 if (!(rmesa->radeon.state.stencil.hwBuffer) ||
817 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
818 ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
819 flags |= RADEON_CLEAR_FASTZ;
820 }
821 }
822
823 if (rmesa->radeon.radeonScreen->kernel_mm)
824 radeonUserClear(ctx, orig_mask);
825 else {
826 radeonKernelClear(ctx, flags);
827 rmesa->radeon.hw.all_dirty = GL_TRUE;
828 }
829 }
830
831 void radeonInitIoctlFuncs( GLcontext *ctx )
832 {
833 ctx->Driver.Clear = radeonClear;
834 ctx->Driver.Finish = radeonFinish;
835 ctx->Driver.Flush = radeonFlush;
836 }
837