2 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Gareth Hughes <gareth@valinux.com>
26 * Kevin E. Martin <martin@valinux.com>
29 #include "dev/drm/drmP.h"
30 #include "dev/drm/drm.h"
31 #include "dev/drm/drm_sarea.h"
32 #include "dev/drm/radeon_drm.h"
33 #include "dev/drm/radeon_drv.h"
35 /* ================================================================
36 * Helper functions for client state checking and fixup
39 static __inline__
int radeon_check_and_fixup_offset(drm_radeon_private_t
*
41 struct drm_file
*file_priv
,
45 u32 fb_end
= dev_priv
->fb_location
+ dev_priv
->fb_size
- 1;
46 struct drm_radeon_driver_file_fields
*radeon_priv
;
48 /* Hrm ... the story of the offset ... So this function converts
49 * the various ideas of what userland clients might have for an
50 * offset in the card address space into an offset into the card
51 * address space :) So with a sane client, it should just keep
52 * the value intact and just do some boundary checking. However,
53 * not all clients are sane. Some older clients pass us 0 based
54 * offsets relative to the start of the framebuffer and some may
55 * assume the AGP aperture it appended to the framebuffer, so we
56 * try to detect those cases and fix them up.
58 * Note: It might be a good idea here to make sure the offset lands
59 * in some "allowed" area to protect things like the PCIE GART...
62 /* First, the best case, the offset already lands in either the
63 * framebuffer or the GART mapped space
65 if (radeon_check_offset(dev_priv
, off
))
68 /* Ok, that didn't happen... now check if we have a zero based
69 * offset that fits in the framebuffer + gart space, apply the
70 * magic offset we get from SETPARAM or calculated from fb_location
72 if (off
< (dev_priv
->fb_size
+ dev_priv
->gart_size
)) {
73 radeon_priv
= file_priv
->driver_priv
;
74 off
+= radeon_priv
->radeon_fb_delta
;
77 /* Finally, assume we aimed at a GART offset if beyond the fb */
79 off
= off
- fb_end
- 1 + dev_priv
->gart_vm_start
;
81 /* Now recheck and fail if out of bounds */
82 if (radeon_check_offset(dev_priv
, off
)) {
83 DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off
);
90 static __inline__
int radeon_check_and_fixup_packets(drm_radeon_private_t
*
92 struct drm_file
*file_priv
,
97 case RADEON_EMIT_PP_MISC
:
98 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
99 &data
[(RADEON_RB3D_DEPTHOFFSET
- RADEON_PP_MISC
) / 4])) {
100 DRM_ERROR("Invalid depth buffer offset\n");
105 case RADEON_EMIT_PP_CNTL
:
106 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
107 &data
[(RADEON_RB3D_COLOROFFSET
- RADEON_PP_CNTL
) / 4])) {
108 DRM_ERROR("Invalid colour buffer offset\n");
113 case R200_EMIT_PP_TXOFFSET_0
:
114 case R200_EMIT_PP_TXOFFSET_1
:
115 case R200_EMIT_PP_TXOFFSET_2
:
116 case R200_EMIT_PP_TXOFFSET_3
:
117 case R200_EMIT_PP_TXOFFSET_4
:
118 case R200_EMIT_PP_TXOFFSET_5
:
119 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
121 DRM_ERROR("Invalid R200 texture offset\n");
126 case RADEON_EMIT_PP_TXFILTER_0
:
127 case RADEON_EMIT_PP_TXFILTER_1
:
128 case RADEON_EMIT_PP_TXFILTER_2
:
129 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
130 &data
[(RADEON_PP_TXOFFSET_0
- RADEON_PP_TXFILTER_0
) / 4])) {
131 DRM_ERROR("Invalid R100 texture offset\n");
136 case R200_EMIT_PP_CUBIC_OFFSETS_0
:
137 case R200_EMIT_PP_CUBIC_OFFSETS_1
:
138 case R200_EMIT_PP_CUBIC_OFFSETS_2
:
139 case R200_EMIT_PP_CUBIC_OFFSETS_3
:
140 case R200_EMIT_PP_CUBIC_OFFSETS_4
:
141 case R200_EMIT_PP_CUBIC_OFFSETS_5
:{
143 for (i
= 0; i
< 5; i
++) {
144 if (radeon_check_and_fixup_offset(dev_priv
,
148 ("Invalid R200 cubic texture offset\n");
155 case RADEON_EMIT_PP_CUBIC_OFFSETS_T0
:
156 case RADEON_EMIT_PP_CUBIC_OFFSETS_T1
:
157 case RADEON_EMIT_PP_CUBIC_OFFSETS_T2
:{
159 for (i
= 0; i
< 5; i
++) {
160 if (radeon_check_and_fixup_offset(dev_priv
,
164 ("Invalid R100 cubic texture offset\n");
171 case R200_EMIT_VAP_CTL
: {
174 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH
, 0);
179 case RADEON_EMIT_RB3D_COLORPITCH
:
180 case RADEON_EMIT_RE_LINE_PATTERN
:
181 case RADEON_EMIT_SE_LINE_WIDTH
:
182 case RADEON_EMIT_PP_LUM_MATRIX
:
183 case RADEON_EMIT_PP_ROT_MATRIX_0
:
184 case RADEON_EMIT_RB3D_STENCILREFMASK
:
185 case RADEON_EMIT_SE_VPORT_XSCALE
:
186 case RADEON_EMIT_SE_CNTL
:
187 case RADEON_EMIT_SE_CNTL_STATUS
:
188 case RADEON_EMIT_RE_MISC
:
189 case RADEON_EMIT_PP_BORDER_COLOR_0
:
190 case RADEON_EMIT_PP_BORDER_COLOR_1
:
191 case RADEON_EMIT_PP_BORDER_COLOR_2
:
192 case RADEON_EMIT_SE_ZBIAS_FACTOR
:
193 case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT
:
194 case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED
:
195 case R200_EMIT_PP_TXCBLEND_0
:
196 case R200_EMIT_PP_TXCBLEND_1
:
197 case R200_EMIT_PP_TXCBLEND_2
:
198 case R200_EMIT_PP_TXCBLEND_3
:
199 case R200_EMIT_PP_TXCBLEND_4
:
200 case R200_EMIT_PP_TXCBLEND_5
:
201 case R200_EMIT_PP_TXCBLEND_6
:
202 case R200_EMIT_PP_TXCBLEND_7
:
203 case R200_EMIT_TCL_LIGHT_MODEL_CTL_0
:
204 case R200_EMIT_TFACTOR_0
:
205 case R200_EMIT_VTX_FMT_0
:
206 case R200_EMIT_MATRIX_SELECT_0
:
207 case R200_EMIT_TEX_PROC_CTL_2
:
208 case R200_EMIT_TCL_UCP_VERT_BLEND_CTL
:
209 case R200_EMIT_PP_TXFILTER_0
:
210 case R200_EMIT_PP_TXFILTER_1
:
211 case R200_EMIT_PP_TXFILTER_2
:
212 case R200_EMIT_PP_TXFILTER_3
:
213 case R200_EMIT_PP_TXFILTER_4
:
214 case R200_EMIT_PP_TXFILTER_5
:
215 case R200_EMIT_VTE_CNTL
:
216 case R200_EMIT_OUTPUT_VTX_COMP_SEL
:
217 case R200_EMIT_PP_TAM_DEBUG3
:
218 case R200_EMIT_PP_CNTL_X
:
219 case R200_EMIT_RB3D_DEPTHXY_OFFSET
:
220 case R200_EMIT_RE_AUX_SCISSOR_CNTL
:
221 case R200_EMIT_RE_SCISSOR_TL_0
:
222 case R200_EMIT_RE_SCISSOR_TL_1
:
223 case R200_EMIT_RE_SCISSOR_TL_2
:
224 case R200_EMIT_SE_VAP_CNTL_STATUS
:
225 case R200_EMIT_SE_VTX_STATE_CNTL
:
226 case R200_EMIT_RE_POINTSIZE
:
227 case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0
:
228 case R200_EMIT_PP_CUBIC_FACES_0
:
229 case R200_EMIT_PP_CUBIC_FACES_1
:
230 case R200_EMIT_PP_CUBIC_FACES_2
:
231 case R200_EMIT_PP_CUBIC_FACES_3
:
232 case R200_EMIT_PP_CUBIC_FACES_4
:
233 case R200_EMIT_PP_CUBIC_FACES_5
:
234 case RADEON_EMIT_PP_TEX_SIZE_0
:
235 case RADEON_EMIT_PP_TEX_SIZE_1
:
236 case RADEON_EMIT_PP_TEX_SIZE_2
:
237 case R200_EMIT_RB3D_BLENDCOLOR
:
238 case R200_EMIT_TCL_POINT_SPRITE_CNTL
:
239 case RADEON_EMIT_PP_CUBIC_FACES_0
:
240 case RADEON_EMIT_PP_CUBIC_FACES_1
:
241 case RADEON_EMIT_PP_CUBIC_FACES_2
:
242 case R200_EMIT_PP_TRI_PERF_CNTL
:
243 case R200_EMIT_PP_AFS_0
:
244 case R200_EMIT_PP_AFS_1
:
245 case R200_EMIT_ATF_TFACTOR
:
246 case R200_EMIT_PP_TXCTLALL_0
:
247 case R200_EMIT_PP_TXCTLALL_1
:
248 case R200_EMIT_PP_TXCTLALL_2
:
249 case R200_EMIT_PP_TXCTLALL_3
:
250 case R200_EMIT_PP_TXCTLALL_4
:
251 case R200_EMIT_PP_TXCTLALL_5
:
252 case R200_EMIT_VAP_PVS_CNTL
:
253 /* These packets don't contain memory offsets */
257 DRM_ERROR("Unknown state packet ID %d\n", id
);
264 static __inline__
int radeon_check_and_fixup_packet3(drm_radeon_private_t
*
266 struct drm_file
*file_priv
,
267 drm_radeon_kcmd_buffer_t
*
271 u32
*cmd
= (u32
*) cmdbuf
->buf
;
275 *cmdsz
= 2 + ((cmd
[0] & RADEON_CP_PACKET_COUNT_MASK
) >> 16);
277 if ((cmd
[0] & 0xc0000000) != RADEON_CP_PACKET3
) {
278 DRM_ERROR("Not a type 3 packet\n");
282 if (4 * *cmdsz
> cmdbuf
->bufsz
) {
283 DRM_ERROR("Packet size larger than size of data provided\n");
287 switch(cmd
[0] & 0xff00) {
288 /* XXX Are there old drivers needing other packets? */
290 case RADEON_3D_DRAW_IMMD
:
291 case RADEON_3D_DRAW_VBUF
:
292 case RADEON_3D_DRAW_INDX
:
293 case RADEON_WAIT_FOR_IDLE
:
295 case RADEON_3D_CLEAR_ZMASK
:
296 /* case RADEON_CP_NEXT_CHAR:
297 case RADEON_CP_PLY_NEXTSCAN:
298 case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
299 /* these packets are safe */
302 case RADEON_CP_3D_DRAW_IMMD_2
:
303 case RADEON_CP_3D_DRAW_VBUF_2
:
304 case RADEON_CP_3D_DRAW_INDX_2
:
305 case RADEON_3D_CLEAR_HIZ
:
306 /* safe but r200 only */
307 if (dev_priv
->microcode_version
!= UCODE_R200
) {
308 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
313 case RADEON_3D_LOAD_VBPNTR
:
314 count
= (cmd
[0] >> 16) & 0x3fff;
316 if (count
> 18) { /* 12 arrays max */
317 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
322 /* carefully check packet contents */
323 narrays
= cmd
[1] & ~0xc000;
326 while ((k
< narrays
) && (i
< (count
+ 2))) {
327 i
++; /* skip attribute field */
328 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
331 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
339 /* have one more to process, they come in pairs */
340 if (radeon_check_and_fixup_offset(dev_priv
,
344 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
351 /* do the counts match what we expect ? */
352 if ((k
!= narrays
) || (i
!= (count
+ 2))) {
354 ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
355 k
, i
, narrays
, count
+ 1);
360 case RADEON_3D_RNDR_GEN_INDX_PRIM
:
361 if (dev_priv
->microcode_version
!= UCODE_R100
) {
362 DRM_ERROR("Invalid 3d packet for r200-class chip\n");
365 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
, &cmd
[1])) {
366 DRM_ERROR("Invalid rndr_gen_indx offset\n");
371 case RADEON_CP_INDX_BUFFER
:
372 if (dev_priv
->microcode_version
!= UCODE_R200
) {
373 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
376 if ((cmd
[1] & 0x8000ffff) != 0x80000810) {
377 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd
[1]);
380 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
, &cmd
[2])) {
381 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd
[2]);
386 case RADEON_CNTL_HOSTDATA_BLT
:
387 case RADEON_CNTL_PAINT_MULTI
:
388 case RADEON_CNTL_BITBLT_MULTI
:
389 /* MSB of opcode: next DWORD GUI_CNTL */
390 if (cmd
[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
391 | RADEON_GMC_DST_PITCH_OFFSET_CNTL
)) {
392 offset
= cmd
[2] << 10;
393 if (radeon_check_and_fixup_offset
394 (dev_priv
, file_priv
, &offset
)) {
395 DRM_ERROR("Invalid first packet offset\n");
398 cmd
[2] = (cmd
[2] & 0xffc00000) | offset
>> 10;
401 if ((cmd
[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL
) &&
402 (cmd
[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL
)) {
403 offset
= cmd
[3] << 10;
404 if (radeon_check_and_fixup_offset
405 (dev_priv
, file_priv
, &offset
)) {
406 DRM_ERROR("Invalid second packet offset\n");
409 cmd
[3] = (cmd
[3] & 0xffc00000) | offset
>> 10;
414 DRM_ERROR("Invalid packet type %x\n", cmd
[0] & 0xff00);
421 /* ================================================================
422 * CP hardware state programming functions
425 static __inline__
void radeon_emit_clip_rect(drm_radeon_private_t
* dev_priv
,
426 struct drm_clip_rect
* box
)
430 DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
431 box
->x1
, box
->y1
, box
->x2
, box
->y2
);
434 OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT
, 0));
435 OUT_RING((box
->y1
<< 16) | box
->x1
);
436 OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT
, 0));
437 OUT_RING(((box
->y2
- 1) << 16) | (box
->x2
- 1));
443 static int radeon_emit_state(drm_radeon_private_t
* dev_priv
,
444 struct drm_file
*file_priv
,
445 drm_radeon_context_regs_t
* ctx
,
446 drm_radeon_texture_regs_t
* tex
,
450 DRM_DEBUG("dirty=0x%08x\n", dirty
);
452 if (dirty
& RADEON_UPLOAD_CONTEXT
) {
453 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
454 &ctx
->rb3d_depthoffset
)) {
455 DRM_ERROR("Invalid depth buffer offset\n");
459 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
460 &ctx
->rb3d_coloroffset
)) {
461 DRM_ERROR("Invalid depth buffer offset\n");
466 OUT_RING(CP_PACKET0(RADEON_PP_MISC
, 6));
467 OUT_RING(ctx
->pp_misc
);
468 OUT_RING(ctx
->pp_fog_color
);
469 OUT_RING(ctx
->re_solid_color
);
470 OUT_RING(ctx
->rb3d_blendcntl
);
471 OUT_RING(ctx
->rb3d_depthoffset
);
472 OUT_RING(ctx
->rb3d_depthpitch
);
473 OUT_RING(ctx
->rb3d_zstencilcntl
);
474 OUT_RING(CP_PACKET0(RADEON_PP_CNTL
, 2));
475 OUT_RING(ctx
->pp_cntl
);
476 OUT_RING(ctx
->rb3d_cntl
);
477 OUT_RING(ctx
->rb3d_coloroffset
);
478 OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH
, 0));
479 OUT_RING(ctx
->rb3d_colorpitch
);
483 if (dirty
& RADEON_UPLOAD_VERTFMT
) {
485 OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT
, 0));
486 OUT_RING(ctx
->se_coord_fmt
);
490 if (dirty
& RADEON_UPLOAD_LINE
) {
492 OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN
, 1));
493 OUT_RING(ctx
->re_line_pattern
);
494 OUT_RING(ctx
->re_line_state
);
495 OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH
, 0));
496 OUT_RING(ctx
->se_line_width
);
500 if (dirty
& RADEON_UPLOAD_BUMPMAP
) {
502 OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX
, 0));
503 OUT_RING(ctx
->pp_lum_matrix
);
504 OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0
, 1));
505 OUT_RING(ctx
->pp_rot_matrix_0
);
506 OUT_RING(ctx
->pp_rot_matrix_1
);
510 if (dirty
& RADEON_UPLOAD_MASKS
) {
512 OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK
, 2));
513 OUT_RING(ctx
->rb3d_stencilrefmask
);
514 OUT_RING(ctx
->rb3d_ropcntl
);
515 OUT_RING(ctx
->rb3d_planemask
);
519 if (dirty
& RADEON_UPLOAD_VIEWPORT
) {
521 OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE
, 5));
522 OUT_RING(ctx
->se_vport_xscale
);
523 OUT_RING(ctx
->se_vport_xoffset
);
524 OUT_RING(ctx
->se_vport_yscale
);
525 OUT_RING(ctx
->se_vport_yoffset
);
526 OUT_RING(ctx
->se_vport_zscale
);
527 OUT_RING(ctx
->se_vport_zoffset
);
531 if (dirty
& RADEON_UPLOAD_SETUP
) {
533 OUT_RING(CP_PACKET0(RADEON_SE_CNTL
, 0));
534 OUT_RING(ctx
->se_cntl
);
535 OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS
, 0));
536 OUT_RING(ctx
->se_cntl_status
);
540 if (dirty
& RADEON_UPLOAD_MISC
) {
542 OUT_RING(CP_PACKET0(RADEON_RE_MISC
, 0));
543 OUT_RING(ctx
->re_misc
);
547 if (dirty
& RADEON_UPLOAD_TEX0
) {
548 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
549 &tex
[0].pp_txoffset
)) {
550 DRM_ERROR("Invalid texture offset for unit 0\n");
555 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0
, 5));
556 OUT_RING(tex
[0].pp_txfilter
);
557 OUT_RING(tex
[0].pp_txformat
);
558 OUT_RING(tex
[0].pp_txoffset
);
559 OUT_RING(tex
[0].pp_txcblend
);
560 OUT_RING(tex
[0].pp_txablend
);
561 OUT_RING(tex
[0].pp_tfactor
);
562 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0
, 0));
563 OUT_RING(tex
[0].pp_border_color
);
567 if (dirty
& RADEON_UPLOAD_TEX1
) {
568 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
569 &tex
[1].pp_txoffset
)) {
570 DRM_ERROR("Invalid texture offset for unit 1\n");
575 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1
, 5));
576 OUT_RING(tex
[1].pp_txfilter
);
577 OUT_RING(tex
[1].pp_txformat
);
578 OUT_RING(tex
[1].pp_txoffset
);
579 OUT_RING(tex
[1].pp_txcblend
);
580 OUT_RING(tex
[1].pp_txablend
);
581 OUT_RING(tex
[1].pp_tfactor
);
582 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1
, 0));
583 OUT_RING(tex
[1].pp_border_color
);
587 if (dirty
& RADEON_UPLOAD_TEX2
) {
588 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
,
589 &tex
[2].pp_txoffset
)) {
590 DRM_ERROR("Invalid texture offset for unit 2\n");
595 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2
, 5));
596 OUT_RING(tex
[2].pp_txfilter
);
597 OUT_RING(tex
[2].pp_txformat
);
598 OUT_RING(tex
[2].pp_txoffset
);
599 OUT_RING(tex
[2].pp_txcblend
);
600 OUT_RING(tex
[2].pp_txablend
);
601 OUT_RING(tex
[2].pp_tfactor
);
602 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2
, 0));
603 OUT_RING(tex
[2].pp_border_color
);
612 static int radeon_emit_state2(drm_radeon_private_t
* dev_priv
,
613 struct drm_file
*file_priv
,
614 drm_radeon_state_t
* state
)
618 if (state
->dirty
& RADEON_UPLOAD_ZBIAS
) {
620 OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR
, 1));
621 OUT_RING(state
->context2
.se_zbias_factor
);
622 OUT_RING(state
->context2
.se_zbias_constant
);
626 return radeon_emit_state(dev_priv
, file_priv
, &state
->context
,
627 state
->tex
, state
->dirty
);
630 /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
631 * 1.3 cmdbuffers allow all previous state to be updated as well as
632 * the tcl scalar and vector areas.
638 } packet
[RADEON_MAX_STATE_PACKETS
] = {
639 {RADEON_PP_MISC
, 7, "RADEON_PP_MISC"},
640 {RADEON_PP_CNTL
, 3, "RADEON_PP_CNTL"},
641 {RADEON_RB3D_COLORPITCH
, 1, "RADEON_RB3D_COLORPITCH"},
642 {RADEON_RE_LINE_PATTERN
, 2, "RADEON_RE_LINE_PATTERN"},
643 {RADEON_SE_LINE_WIDTH
, 1, "RADEON_SE_LINE_WIDTH"},
644 {RADEON_PP_LUM_MATRIX
, 1, "RADEON_PP_LUM_MATRIX"},
645 {RADEON_PP_ROT_MATRIX_0
, 2, "RADEON_PP_ROT_MATRIX_0"},
646 {RADEON_RB3D_STENCILREFMASK
, 3, "RADEON_RB3D_STENCILREFMASK"},
647 {RADEON_SE_VPORT_XSCALE
, 6, "RADEON_SE_VPORT_XSCALE"},
648 {RADEON_SE_CNTL
, 2, "RADEON_SE_CNTL"},
649 {RADEON_SE_CNTL_STATUS
, 1, "RADEON_SE_CNTL_STATUS"},
650 {RADEON_RE_MISC
, 1, "RADEON_RE_MISC"},
651 {RADEON_PP_TXFILTER_0
, 6, "RADEON_PP_TXFILTER_0"},
652 {RADEON_PP_BORDER_COLOR_0
, 1, "RADEON_PP_BORDER_COLOR_0"},
653 {RADEON_PP_TXFILTER_1
, 6, "RADEON_PP_TXFILTER_1"},
654 {RADEON_PP_BORDER_COLOR_1
, 1, "RADEON_PP_BORDER_COLOR_1"},
655 {RADEON_PP_TXFILTER_2
, 6, "RADEON_PP_TXFILTER_2"},
656 {RADEON_PP_BORDER_COLOR_2
, 1, "RADEON_PP_BORDER_COLOR_2"},
657 {RADEON_SE_ZBIAS_FACTOR
, 2, "RADEON_SE_ZBIAS_FACTOR"},
658 {RADEON_SE_TCL_OUTPUT_VTX_FMT
, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
659 {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
, 17,
660 "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
661 {R200_PP_TXCBLEND_0
, 4, "R200_PP_TXCBLEND_0"},
662 {R200_PP_TXCBLEND_1
, 4, "R200_PP_TXCBLEND_1"},
663 {R200_PP_TXCBLEND_2
, 4, "R200_PP_TXCBLEND_2"},
664 {R200_PP_TXCBLEND_3
, 4, "R200_PP_TXCBLEND_3"},
665 {R200_PP_TXCBLEND_4
, 4, "R200_PP_TXCBLEND_4"},
666 {R200_PP_TXCBLEND_5
, 4, "R200_PP_TXCBLEND_5"},
667 {R200_PP_TXCBLEND_6
, 4, "R200_PP_TXCBLEND_6"},
668 {R200_PP_TXCBLEND_7
, 4, "R200_PP_TXCBLEND_7"},
669 {R200_SE_TCL_LIGHT_MODEL_CTL_0
, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
670 {R200_PP_TFACTOR_0
, 6, "R200_PP_TFACTOR_0"},
671 {R200_SE_VTX_FMT_0
, 4, "R200_SE_VTX_FMT_0"},
672 {R200_SE_VAP_CNTL
, 1, "R200_SE_VAP_CNTL"},
673 {R200_SE_TCL_MATRIX_SEL_0
, 5, "R200_SE_TCL_MATRIX_SEL_0"},
674 {R200_SE_TCL_TEX_PROC_CTL_2
, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
675 {R200_SE_TCL_UCP_VERT_BLEND_CTL
, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
676 {R200_PP_TXFILTER_0
, 6, "R200_PP_TXFILTER_0"},
677 {R200_PP_TXFILTER_1
, 6, "R200_PP_TXFILTER_1"},
678 {R200_PP_TXFILTER_2
, 6, "R200_PP_TXFILTER_2"},
679 {R200_PP_TXFILTER_3
, 6, "R200_PP_TXFILTER_3"},
680 {R200_PP_TXFILTER_4
, 6, "R200_PP_TXFILTER_4"},
681 {R200_PP_TXFILTER_5
, 6, "R200_PP_TXFILTER_5"},
682 {R200_PP_TXOFFSET_0
, 1, "R200_PP_TXOFFSET_0"},
683 {R200_PP_TXOFFSET_1
, 1, "R200_PP_TXOFFSET_1"},
684 {R200_PP_TXOFFSET_2
, 1, "R200_PP_TXOFFSET_2"},
685 {R200_PP_TXOFFSET_3
, 1, "R200_PP_TXOFFSET_3"},
686 {R200_PP_TXOFFSET_4
, 1, "R200_PP_TXOFFSET_4"},
687 {R200_PP_TXOFFSET_5
, 1, "R200_PP_TXOFFSET_5"},
688 {R200_SE_VTE_CNTL
, 1, "R200_SE_VTE_CNTL"},
689 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL
, 1,
690 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
691 {R200_PP_TAM_DEBUG3
, 1, "R200_PP_TAM_DEBUG3"},
692 {R200_PP_CNTL_X
, 1, "R200_PP_CNTL_X"},
693 {R200_RB3D_DEPTHXY_OFFSET
, 1, "R200_RB3D_DEPTHXY_OFFSET"},
694 {R200_RE_AUX_SCISSOR_CNTL
, 1, "R200_RE_AUX_SCISSOR_CNTL"},
695 {R200_RE_SCISSOR_TL_0
, 2, "R200_RE_SCISSOR_TL_0"},
696 {R200_RE_SCISSOR_TL_1
, 2, "R200_RE_SCISSOR_TL_1"},
697 {R200_RE_SCISSOR_TL_2
, 2, "R200_RE_SCISSOR_TL_2"},
698 {R200_SE_VAP_CNTL_STATUS
, 1, "R200_SE_VAP_CNTL_STATUS"},
699 {R200_SE_VTX_STATE_CNTL
, 1, "R200_SE_VTX_STATE_CNTL"},
700 {R200_RE_POINTSIZE
, 1, "R200_RE_POINTSIZE"},
701 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0
, 4,
702 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
703 {R200_PP_CUBIC_FACES_0
, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
704 {R200_PP_CUBIC_OFFSET_F1_0
, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
705 {R200_PP_CUBIC_FACES_1
, 1, "R200_PP_CUBIC_FACES_1"},
706 {R200_PP_CUBIC_OFFSET_F1_1
, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
707 {R200_PP_CUBIC_FACES_2
, 1, "R200_PP_CUBIC_FACES_2"},
708 {R200_PP_CUBIC_OFFSET_F1_2
, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
709 {R200_PP_CUBIC_FACES_3
, 1, "R200_PP_CUBIC_FACES_3"},
710 {R200_PP_CUBIC_OFFSET_F1_3
, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
711 {R200_PP_CUBIC_FACES_4
, 1, "R200_PP_CUBIC_FACES_4"},
712 {R200_PP_CUBIC_OFFSET_F1_4
, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
713 {R200_PP_CUBIC_FACES_5
, 1, "R200_PP_CUBIC_FACES_5"},
714 {R200_PP_CUBIC_OFFSET_F1_5
, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
715 {RADEON_PP_TEX_SIZE_0
, 2, "RADEON_PP_TEX_SIZE_0"},
716 {RADEON_PP_TEX_SIZE_1
, 2, "RADEON_PP_TEX_SIZE_1"},
717 {RADEON_PP_TEX_SIZE_2
, 2, "RADEON_PP_TEX_SIZE_2"},
718 {R200_RB3D_BLENDCOLOR
, 3, "R200_RB3D_BLENDCOLOR"},
719 {R200_SE_TCL_POINT_SPRITE_CNTL
, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
720 {RADEON_PP_CUBIC_FACES_0
, 1, "RADEON_PP_CUBIC_FACES_0"},
721 {RADEON_PP_CUBIC_OFFSET_T0_0
, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
722 {RADEON_PP_CUBIC_FACES_1
, 1, "RADEON_PP_CUBIC_FACES_1"},
723 {RADEON_PP_CUBIC_OFFSET_T1_0
, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
724 {RADEON_PP_CUBIC_FACES_2
, 1, "RADEON_PP_CUBIC_FACES_2"},
725 {RADEON_PP_CUBIC_OFFSET_T2_0
, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
726 {R200_PP_TRI_PERF
, 2, "R200_PP_TRI_PERF"},
727 {R200_PP_AFS_0
, 32, "R200_PP_AFS_0"}, /* 85 */
728 {R200_PP_AFS_1
, 32, "R200_PP_AFS_1"},
729 {R200_PP_TFACTOR_0
, 8, "R200_ATF_TFACTOR"},
730 {R200_PP_TXFILTER_0
, 8, "R200_PP_TXCTLALL_0"},
731 {R200_PP_TXFILTER_1
, 8, "R200_PP_TXCTLALL_1"},
732 {R200_PP_TXFILTER_2
, 8, "R200_PP_TXCTLALL_2"},
733 {R200_PP_TXFILTER_3
, 8, "R200_PP_TXCTLALL_3"},
734 {R200_PP_TXFILTER_4
, 8, "R200_PP_TXCTLALL_4"},
735 {R200_PP_TXFILTER_5
, 8, "R200_PP_TXCTLALL_5"},
736 {R200_VAP_PVS_CNTL_1
, 2, "R200_VAP_PVS_CNTL"},
739 /* ================================================================
740 * Performance monitoring functions
743 static void radeon_clear_box(drm_radeon_private_t
* dev_priv
,
744 int x
, int y
, int w
, int h
, int r
, int g
, int b
)
749 x
+= dev_priv
->sarea_priv
->boxes
[0].x1
;
750 y
+= dev_priv
->sarea_priv
->boxes
[0].y1
;
752 switch (dev_priv
->color_fmt
) {
753 case RADEON_COLOR_FORMAT_RGB565
:
754 color
= (((r
& 0xf8) << 8) |
755 ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3));
757 case RADEON_COLOR_FORMAT_ARGB8888
:
759 color
= (((0xff) << 24) | (r
<< 16) | (g
<< 8) | b
);
764 RADEON_WAIT_UNTIL_3D_IDLE();
765 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK
, 0));
766 OUT_RING(0xffffffff);
771 OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI
, 4));
772 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
773 RADEON_GMC_BRUSH_SOLID_COLOR
|
774 (dev_priv
->color_fmt
<< 8) |
775 RADEON_GMC_SRC_DATATYPE_COLOR
|
776 RADEON_ROP3_P
| RADEON_GMC_CLR_CMP_CNTL_DIS
);
778 if (dev_priv
->sarea_priv
->pfCurrentPage
== 1) {
779 OUT_RING(dev_priv
->front_pitch_offset
);
781 OUT_RING(dev_priv
->back_pitch_offset
);
786 OUT_RING((x
<< 16) | y
);
787 OUT_RING((w
<< 16) | h
);
792 static void radeon_cp_performance_boxes(drm_radeon_private_t
*dev_priv
)
794 /* Collapse various things into a wait flag -- trying to
795 * guess if userspase slept -- better just to have them tell us.
797 if (dev_priv
->stats
.last_frame_reads
> 1 ||
798 dev_priv
->stats
.last_clear_reads
> dev_priv
->stats
.clears
) {
799 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
802 if (dev_priv
->stats
.freelist_loops
) {
803 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
806 /* Purple box for page flipping
808 if (dev_priv
->stats
.boxes
& RADEON_BOX_FLIP
)
809 radeon_clear_box(dev_priv
, 4, 4, 8, 8, 255, 0, 255);
811 /* Red box if we have to wait for idle at any point
813 if (dev_priv
->stats
.boxes
& RADEON_BOX_WAIT_IDLE
)
814 radeon_clear_box(dev_priv
, 16, 4, 8, 8, 255, 0, 0);
816 /* Blue box: lost context?
819 /* Yellow box for texture swaps
821 if (dev_priv
->stats
.boxes
& RADEON_BOX_TEXTURE_LOAD
)
822 radeon_clear_box(dev_priv
, 40, 4, 8, 8, 255, 255, 0);
824 /* Green box if hardware never idles (as far as we can tell)
826 if (!(dev_priv
->stats
.boxes
& RADEON_BOX_DMA_IDLE
))
827 radeon_clear_box(dev_priv
, 64, 4, 8, 8, 0, 255, 0);
829 /* Draw bars indicating number of buffers allocated
830 * (not a great measure, easily confused)
832 if (dev_priv
->stats
.requested_bufs
) {
833 if (dev_priv
->stats
.requested_bufs
> 100)
834 dev_priv
->stats
.requested_bufs
= 100;
836 radeon_clear_box(dev_priv
, 4, 16,
837 dev_priv
->stats
.requested_bufs
, 4,
841 memset(&dev_priv
->stats
, 0, sizeof(dev_priv
->stats
));
845 /* ================================================================
846 * CP command dispatch functions
849 static void radeon_cp_dispatch_clear(struct drm_device
* dev
,
850 drm_radeon_clear_t
* clear
,
851 drm_radeon_clear_rect_t
* depth_boxes
)
853 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
854 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
855 drm_radeon_depth_clear_t
*depth_clear
= &dev_priv
->depth_clear
;
856 int nbox
= sarea_priv
->nbox
;
857 struct drm_clip_rect
*pbox
= sarea_priv
->boxes
;
858 unsigned int flags
= clear
->flags
;
859 u32 rb3d_cntl
= 0, rb3d_stencilrefmask
= 0;
862 DRM_DEBUG("flags = 0x%x\n", flags
);
864 dev_priv
->stats
.clears
++;
866 if (sarea_priv
->pfCurrentPage
== 1) {
867 unsigned int tmp
= flags
;
869 flags
&= ~(RADEON_FRONT
| RADEON_BACK
);
870 if (tmp
& RADEON_FRONT
)
871 flags
|= RADEON_BACK
;
872 if (tmp
& RADEON_BACK
)
873 flags
|= RADEON_FRONT
;
876 if (flags
& (RADEON_FRONT
| RADEON_BACK
)) {
880 /* Ensure the 3D stream is idle before doing a
881 * 2D fill to clear the front or back buffer.
883 RADEON_WAIT_UNTIL_3D_IDLE();
885 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK
, 0));
886 OUT_RING(clear
->color_mask
);
890 /* Make sure we restore the 3D state next time.
892 sarea_priv
->ctx_owner
= 0;
894 for (i
= 0; i
< nbox
; i
++) {
897 int w
= pbox
[i
].x2
- x
;
898 int h
= pbox
[i
].y2
- y
;
900 DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
903 if (flags
& RADEON_FRONT
) {
907 (RADEON_CNTL_PAINT_MULTI
, 4));
908 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
909 RADEON_GMC_BRUSH_SOLID_COLOR
|
912 RADEON_GMC_SRC_DATATYPE_COLOR
|
914 RADEON_GMC_CLR_CMP_CNTL_DIS
);
916 OUT_RING(dev_priv
->front_pitch_offset
);
917 OUT_RING(clear
->clear_color
);
919 OUT_RING((x
<< 16) | y
);
920 OUT_RING((w
<< 16) | h
);
925 if (flags
& RADEON_BACK
) {
929 (RADEON_CNTL_PAINT_MULTI
, 4));
930 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
931 RADEON_GMC_BRUSH_SOLID_COLOR
|
934 RADEON_GMC_SRC_DATATYPE_COLOR
|
936 RADEON_GMC_CLR_CMP_CNTL_DIS
);
938 OUT_RING(dev_priv
->back_pitch_offset
);
939 OUT_RING(clear
->clear_color
);
941 OUT_RING((x
<< 16) | y
);
942 OUT_RING((w
<< 16) | h
);
950 /* no docs available, based on reverse engeneering by Stephane Marchesin */
951 if ((flags
& (RADEON_DEPTH
| RADEON_STENCIL
))
952 && (flags
& RADEON_CLEAR_FASTZ
)) {
955 int depthpixperline
=
956 dev_priv
->depth_fmt
==
957 RADEON_DEPTH_FORMAT_16BIT_INT_Z
? (dev_priv
->depth_pitch
/
963 u32 tempRB3D_DEPTHCLEARVALUE
= clear
->clear_depth
|
964 ((clear
->depth_mask
& 0xff) << 24);
966 /* Make sure we restore the 3D state next time.
967 * we haven't touched any "normal" state - still need this?
969 sarea_priv
->ctx_owner
= 0;
971 if ((dev_priv
->flags
& RADEON_HAS_HIERZ
)
972 && (flags
& RADEON_USE_HIERZ
)) {
973 /* FIXME : reverse engineer that for Rx00 cards */
974 /* FIXME : the mask supposedly contains low-res z values. So can't set
975 just to the max (0xff? or actually 0x3fff?), need to take z clear
976 value into account? */
977 /* pattern seems to work for r100, though get slight
978 rendering errors with glxgears. If hierz is not enabled for r100,
979 only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
980 other ones are ignored, and the same clear mask can be used. That's
981 very different behaviour than R200 which needs different clear mask
982 and different number of tiles to clear if hierz is enabled or not !?!
984 clearmask
= (0xff << 22) | (0xff << 6) | 0x003f003f;
986 /* clear mask : chooses the clearing pattern.
987 rv250: could be used to clear only parts of macrotiles
988 (but that would get really complicated...)?
989 bit 0 and 1 (either or both of them ?!?!) are used to
990 not clear tile (or maybe one of the bits indicates if the tile is
991 compressed or not), bit 2 and 3 to not clear tile 1,...,.
992 Pattern is as follows:
993 | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
994 bits -------------------------------------------------
995 | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
996 rv100: clearmask covers 2x8 4x1 tiles, but one clear still
997 covers 256 pixels ?!?
1003 RADEON_WAIT_UNTIL_2D_IDLE();
1004 OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE
,
1005 tempRB3D_DEPTHCLEARVALUE
);
1006 /* what offset is this exactly ? */
1007 OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET
, 0);
1008 /* need ctlstat, otherwise get some strange black flickering */
1009 OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT
,
1010 RADEON_RB3D_ZC_FLUSH_ALL
);
1013 for (i
= 0; i
< nbox
; i
++) {
1014 int tileoffset
, nrtilesx
, nrtilesy
, j
;
1015 /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
1016 if ((dev_priv
->flags
& RADEON_HAS_HIERZ
)
1017 && !(dev_priv
->microcode_version
== UCODE_R200
)) {
1018 /* FIXME : figure this out for r200 (when hierz is enabled). Or
1019 maybe r200 actually doesn't need to put the low-res z value into
1020 the tile cache like r100, but just needs to clear the hi-level z-buffer?
1021 Works for R100, both with hierz and without.
1022 R100 seems to operate on 2x1 8x8 tiles, but...
1023 odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
1024 problematic with resolutions which are not 64 pix aligned? */
1026 ((pbox
[i
].y1
>> 3) * depthpixperline
+
1029 ((pbox
[i
].x2
& ~63) -
1030 (pbox
[i
].x1
& ~63)) >> 4;
1032 (pbox
[i
].y2
>> 3) - (pbox
[i
].y1
>> 3);
1033 for (j
= 0; j
<= nrtilesy
; j
++) {
1036 (RADEON_3D_CLEAR_ZMASK
, 2));
1038 OUT_RING(tileoffset
* 8);
1039 /* the number of tiles to clear */
1040 OUT_RING(nrtilesx
+ 4);
1041 /* clear mask : chooses the clearing pattern. */
1042 OUT_RING(clearmask
);
1044 tileoffset
+= depthpixperline
>> 6;
1046 } else if (dev_priv
->microcode_version
== UCODE_R200
) {
1047 /* works for rv250. */
1048 /* find first macro tile (8x2 4x4 z-pixels on rv250) */
1050 ((pbox
[i
].y1
>> 3) * depthpixperline
+
1053 (pbox
[i
].x2
>> 5) - (pbox
[i
].x1
>> 5);
1055 (pbox
[i
].y2
>> 3) - (pbox
[i
].y1
>> 3);
1056 for (j
= 0; j
<= nrtilesy
; j
++) {
1059 (RADEON_3D_CLEAR_ZMASK
, 2));
1061 /* judging by the first tile offset needed, could possibly
1062 directly address/clear 4x4 tiles instead of 8x2 * 4x4
1063 macro tiles, though would still need clear mask for
1064 right/bottom if truely 4x4 granularity is desired ? */
1065 OUT_RING(tileoffset
* 16);
1066 /* the number of tiles to clear */
1067 OUT_RING(nrtilesx
+ 1);
1068 /* clear mask : chooses the clearing pattern. */
1069 OUT_RING(clearmask
);
1071 tileoffset
+= depthpixperline
>> 5;
1073 } else { /* rv 100 */
1074 /* rv100 might not need 64 pix alignment, who knows */
1075 /* offsets are, hmm, weird */
1077 ((pbox
[i
].y1
>> 4) * depthpixperline
+
1080 ((pbox
[i
].x2
& ~63) -
1081 (pbox
[i
].x1
& ~63)) >> 4;
1083 (pbox
[i
].y2
>> 4) - (pbox
[i
].y1
>> 4);
1084 for (j
= 0; j
<= nrtilesy
; j
++) {
1087 (RADEON_3D_CLEAR_ZMASK
, 2));
1088 OUT_RING(tileoffset
* 128);
1089 /* the number of tiles to clear */
1090 OUT_RING(nrtilesx
+ 4);
1091 /* clear mask : chooses the clearing pattern. */
1092 OUT_RING(clearmask
);
1094 tileoffset
+= depthpixperline
>> 6;
1099 /* TODO don't always clear all hi-level z tiles */
1100 if ((dev_priv
->flags
& RADEON_HAS_HIERZ
)
1101 && (dev_priv
->microcode_version
== UCODE_R200
)
1102 && (flags
& RADEON_USE_HIERZ
))
1103 /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
1104 /* FIXME : the mask supposedly contains low-res z values. So can't set
1105 just to the max (0xff? or actually 0x3fff?), need to take z clear
1106 value into account? */
1109 OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ
, 2));
1110 OUT_RING(0x0); /* First tile */
1112 OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
1117 /* We have to clear the depth and/or stencil buffers by
1118 * rendering a quad into just those buffers. Thus, we have to
1119 * make sure the 3D engine is configured correctly.
1121 else if ((dev_priv
->microcode_version
== UCODE_R200
) &&
1122 (flags
& (RADEON_DEPTH
| RADEON_STENCIL
))) {
1127 int tempRB3D_ZSTENCILCNTL
;
1128 int tempRB3D_STENCILREFMASK
;
1129 int tempRB3D_PLANEMASK
;
1131 int tempSE_VTE_CNTL
;
1132 int tempSE_VTX_FMT_0
;
1133 int tempSE_VTX_FMT_1
;
1134 int tempSE_VAP_CNTL
;
1135 int tempRE_AUX_SCISSOR_CNTL
;
1140 tempRB3D_CNTL
= depth_clear
->rb3d_cntl
;
1142 tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
1143 tempRB3D_STENCILREFMASK
= 0x0;
1145 tempSE_CNTL
= depth_clear
->se_cntl
;
1149 tempSE_VAP_CNTL
= ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
1151 SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT
));
1153 tempRB3D_PLANEMASK
= 0x0;
1155 tempRE_AUX_SCISSOR_CNTL
= 0x0;
1158 SE_VTE_CNTL__VTX_XY_FMT_MASK
| SE_VTE_CNTL__VTX_Z_FMT_MASK
;
1160 /* Vertex format (X, Y, Z, W) */
1162 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK
|
1163 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK
;
1164 tempSE_VTX_FMT_1
= 0x0;
1167 * Depth buffer specific enables
1169 if (flags
& RADEON_DEPTH
) {
1170 /* Enable depth buffer */
1171 tempRB3D_CNTL
|= RADEON_Z_ENABLE
;
1173 /* Disable depth buffer */
1174 tempRB3D_CNTL
&= ~RADEON_Z_ENABLE
;
1178 * Stencil buffer specific enables
1180 if (flags
& RADEON_STENCIL
) {
1181 tempRB3D_CNTL
|= RADEON_STENCIL_ENABLE
;
1182 tempRB3D_STENCILREFMASK
= clear
->depth_mask
;
1184 tempRB3D_CNTL
&= ~RADEON_STENCIL_ENABLE
;
1185 tempRB3D_STENCILREFMASK
= 0x00000000;
1188 if (flags
& RADEON_USE_COMP_ZBUF
) {
1189 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_COMPRESSION_ENABLE
|
1190 RADEON_Z_DECOMPRESSION_ENABLE
;
1192 if (flags
& RADEON_USE_HIERZ
) {
1193 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_HIERARCHY_ENABLE
;
1197 RADEON_WAIT_UNTIL_2D_IDLE();
1199 OUT_RING_REG(RADEON_PP_CNTL
, tempPP_CNTL
);
1200 OUT_RING_REG(R200_RE_CNTL
, tempRE_CNTL
);
1201 OUT_RING_REG(RADEON_RB3D_CNTL
, tempRB3D_CNTL
);
1202 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL
, tempRB3D_ZSTENCILCNTL
);
1203 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK
,
1204 tempRB3D_STENCILREFMASK
);
1205 OUT_RING_REG(RADEON_RB3D_PLANEMASK
, tempRB3D_PLANEMASK
);
1206 OUT_RING_REG(RADEON_SE_CNTL
, tempSE_CNTL
);
1207 OUT_RING_REG(R200_SE_VTE_CNTL
, tempSE_VTE_CNTL
);
1208 OUT_RING_REG(R200_SE_VTX_FMT_0
, tempSE_VTX_FMT_0
);
1209 OUT_RING_REG(R200_SE_VTX_FMT_1
, tempSE_VTX_FMT_1
);
1210 OUT_RING_REG(R200_SE_VAP_CNTL
, tempSE_VAP_CNTL
);
1211 OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL
, tempRE_AUX_SCISSOR_CNTL
);
1214 /* Make sure we restore the 3D state next time.
1216 sarea_priv
->ctx_owner
= 0;
1218 for (i
= 0; i
< nbox
; i
++) {
1220 /* Funny that this should be required --
1223 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1226 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2
, 12));
1227 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST
|
1228 RADEON_PRIM_WALK_RING
|
1229 (3 << RADEON_NUM_VERTICES_SHIFT
)));
1230 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1231 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y1
]);
1232 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1233 OUT_RING(0x3f800000);
1234 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1235 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1236 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1237 OUT_RING(0x3f800000);
1238 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X2
]);
1239 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1240 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1241 OUT_RING(0x3f800000);
1244 } else if ((flags
& (RADEON_DEPTH
| RADEON_STENCIL
))) {
1246 int tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
1248 rb3d_cntl
= depth_clear
->rb3d_cntl
;
1250 if (flags
& RADEON_DEPTH
) {
1251 rb3d_cntl
|= RADEON_Z_ENABLE
;
1253 rb3d_cntl
&= ~RADEON_Z_ENABLE
;
1256 if (flags
& RADEON_STENCIL
) {
1257 rb3d_cntl
|= RADEON_STENCIL_ENABLE
;
1258 rb3d_stencilrefmask
= clear
->depth_mask
; /* misnamed field */
1260 rb3d_cntl
&= ~RADEON_STENCIL_ENABLE
;
1261 rb3d_stencilrefmask
= 0x00000000;
1264 if (flags
& RADEON_USE_COMP_ZBUF
) {
1265 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_COMPRESSION_ENABLE
|
1266 RADEON_Z_DECOMPRESSION_ENABLE
;
1268 if (flags
& RADEON_USE_HIERZ
) {
1269 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_HIERARCHY_ENABLE
;
1273 RADEON_WAIT_UNTIL_2D_IDLE();
1275 OUT_RING(CP_PACKET0(RADEON_PP_CNTL
, 1));
1276 OUT_RING(0x00000000);
1277 OUT_RING(rb3d_cntl
);
1279 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL
, tempRB3D_ZSTENCILCNTL
);
1280 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK
, rb3d_stencilrefmask
);
1281 OUT_RING_REG(RADEON_RB3D_PLANEMASK
, 0x00000000);
1282 OUT_RING_REG(RADEON_SE_CNTL
, depth_clear
->se_cntl
);
1285 /* Make sure we restore the 3D state next time.
1287 sarea_priv
->ctx_owner
= 0;
1289 for (i
= 0; i
< nbox
; i
++) {
1291 /* Funny that this should be required --
1294 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1298 OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD
, 13));
1299 OUT_RING(RADEON_VTX_Z_PRESENT
|
1300 RADEON_VTX_PKCOLOR_PRESENT
);
1301 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST
|
1302 RADEON_PRIM_WALK_RING
|
1303 RADEON_MAOS_ENABLE
|
1304 RADEON_VTX_FMT_RADEON_MODE
|
1305 (3 << RADEON_NUM_VERTICES_SHIFT
)));
1307 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1308 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y1
]);
1309 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1312 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1313 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1314 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1317 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X2
]);
1318 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1319 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1326 /* Increment the clear counter. The client-side 3D driver must
1327 * wait on this value before performing the clear ioctl. We
1328 * need this because the card's so damned fast...
1330 sarea_priv
->last_clear
++;
1334 RADEON_CLEAR_AGE(sarea_priv
->last_clear
);
1335 RADEON_WAIT_UNTIL_IDLE();
1340 static void radeon_cp_dispatch_swap(struct drm_device
*dev
)
1342 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1343 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1344 int nbox
= sarea_priv
->nbox
;
1345 struct drm_clip_rect
*pbox
= sarea_priv
->boxes
;
1350 /* Do some trivial performance monitoring...
1352 if (dev_priv
->do_boxes
)
1353 radeon_cp_performance_boxes(dev_priv
);
1355 /* Wait for the 3D stream to idle before dispatching the bitblt.
1356 * This will prevent data corruption between the two streams.
1360 RADEON_WAIT_UNTIL_3D_IDLE();
1364 for (i
= 0; i
< nbox
; i
++) {
1367 int w
= pbox
[i
].x2
- x
;
1368 int h
= pbox
[i
].y2
- y
;
1370 DRM_DEBUG("%d,%d-%d,%d\n", x
, y
, w
, h
);
1374 OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL
, 0));
1375 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
1376 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1377 RADEON_GMC_BRUSH_NONE
|
1378 (dev_priv
->color_fmt
<< 8) |
1379 RADEON_GMC_SRC_DATATYPE_COLOR
|
1381 RADEON_DP_SRC_SOURCE_MEMORY
|
1382 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
1384 /* Make this work even if front & back are flipped:
1386 OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET
, 1));
1387 if (sarea_priv
->pfCurrentPage
== 0) {
1388 OUT_RING(dev_priv
->back_pitch_offset
);
1389 OUT_RING(dev_priv
->front_pitch_offset
);
1391 OUT_RING(dev_priv
->front_pitch_offset
);
1392 OUT_RING(dev_priv
->back_pitch_offset
);
1395 OUT_RING(CP_PACKET0(RADEON_SRC_X_Y
, 2));
1396 OUT_RING((x
<< 16) | y
);
1397 OUT_RING((x
<< 16) | y
);
1398 OUT_RING((w
<< 16) | h
);
1403 /* Increment the frame counter. The client-side 3D driver must
1404 * throttle the framerate by waiting for this value before
1405 * performing the swapbuffer ioctl.
1407 sarea_priv
->last_frame
++;
1411 RADEON_FRAME_AGE(sarea_priv
->last_frame
);
1412 RADEON_WAIT_UNTIL_2D_IDLE();
1417 static void radeon_cp_dispatch_flip(struct drm_device
*dev
)
1419 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1420 struct drm_sarea
*sarea
= (struct drm_sarea
*)dev_priv
->sarea
->handle
;
1421 int offset
= (dev_priv
->sarea_priv
->pfCurrentPage
== 1)
1422 ? dev_priv
->front_offset
: dev_priv
->back_offset
;
1424 DRM_DEBUG("pfCurrentPage=%d\n",
1425 dev_priv
->sarea_priv
->pfCurrentPage
);
1427 /* Do some trivial performance monitoring...
1429 if (dev_priv
->do_boxes
) {
1430 dev_priv
->stats
.boxes
|= RADEON_BOX_FLIP
;
1431 radeon_cp_performance_boxes(dev_priv
);
1434 /* Update the frame offsets for both CRTCs
1438 RADEON_WAIT_UNTIL_3D_IDLE();
1439 OUT_RING_REG(RADEON_CRTC_OFFSET
,
1440 ((sarea
->frame
.y
* dev_priv
->front_pitch
+
1441 sarea
->frame
.x
* (dev_priv
->color_fmt
- 2)) & ~7)
1443 OUT_RING_REG(RADEON_CRTC2_OFFSET
, dev_priv
->sarea_priv
->crtc2_base
1448 /* Increment the frame counter. The client-side 3D driver must
1449 * throttle the framerate by waiting for this value before
1450 * performing the swapbuffer ioctl.
1452 dev_priv
->sarea_priv
->last_frame
++;
1453 dev_priv
->sarea_priv
->pfCurrentPage
=
1454 1 - dev_priv
->sarea_priv
->pfCurrentPage
;
1458 RADEON_FRAME_AGE(dev_priv
->sarea_priv
->last_frame
);
1463 static int bad_prim_vertex_nr(int primitive
, int nr
)
1465 switch (primitive
& RADEON_PRIM_TYPE_MASK
) {
1466 case RADEON_PRIM_TYPE_NONE
:
1467 case RADEON_PRIM_TYPE_POINT
:
1469 case RADEON_PRIM_TYPE_LINE
:
1470 return (nr
& 1) || nr
== 0;
1471 case RADEON_PRIM_TYPE_LINE_STRIP
:
1473 case RADEON_PRIM_TYPE_TRI_LIST
:
1474 case RADEON_PRIM_TYPE_3VRT_POINT_LIST
:
1475 case RADEON_PRIM_TYPE_3VRT_LINE_LIST
:
1476 case RADEON_PRIM_TYPE_RECT_LIST
:
1477 return nr
% 3 || nr
== 0;
1478 case RADEON_PRIM_TYPE_TRI_FAN
:
1479 case RADEON_PRIM_TYPE_TRI_STRIP
:
1488 unsigned int finish
;
1490 unsigned int numverts
;
1491 unsigned int offset
;
1492 unsigned int vc_format
;
1493 } drm_radeon_tcl_prim_t
;
1495 static void radeon_cp_dispatch_vertex(struct drm_device
* dev
,
1496 struct drm_buf
* buf
,
1497 drm_radeon_tcl_prim_t
* prim
)
1499 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1500 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1501 int offset
= dev_priv
->gart_buffers_offset
+ buf
->offset
+ prim
->start
;
1502 int numverts
= (int)prim
->numverts
;
1503 int nbox
= sarea_priv
->nbox
;
1507 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1509 prim
->vc_format
, prim
->start
, prim
->finish
, prim
->numverts
);
1511 if (bad_prim_vertex_nr(prim
->prim
, prim
->numverts
)) {
1512 DRM_ERROR("bad prim %x numverts %d\n",
1513 prim
->prim
, prim
->numverts
);
1518 /* Emit the next cliprect */
1520 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1523 /* Emit the vertex buffer rendering commands */
1526 OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM
, 3));
1529 OUT_RING(prim
->vc_format
);
1530 OUT_RING(prim
->prim
| RADEON_PRIM_WALK_LIST
|
1531 RADEON_COLOR_ORDER_RGBA
|
1532 RADEON_VTX_FMT_RADEON_MODE
|
1533 (numverts
<< RADEON_NUM_VERTICES_SHIFT
));
1541 static void radeon_cp_discard_buffer(struct drm_device
*dev
, struct drm_buf
*buf
)
1543 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1544 drm_radeon_buf_priv_t
*buf_priv
= buf
->dev_private
;
1547 buf_priv
->age
= ++dev_priv
->sarea_priv
->last_dispatch
;
1549 /* Emit the vertex buffer age */
1550 if ((dev_priv
->flags
& RADEON_FAMILY_MASK
) >= CHIP_R600
) {
1552 R600_DISPATCH_AGE(buf_priv
->age
);
1556 RADEON_DISPATCH_AGE(buf_priv
->age
);
1564 static void radeon_cp_dispatch_indirect(struct drm_device
* dev
,
1565 struct drm_buf
* buf
, int start
, int end
)
1567 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1569 DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf
->idx
, start
, end
);
1572 int offset
= (dev_priv
->gart_buffers_offset
1573 + buf
->offset
+ start
);
1574 int dwords
= (end
- start
+ 3) / sizeof(u32
);
1576 /* Indirect buffer data must be an even number of
1577 * dwords, so if we've been given an odd number we must
1578 * pad the data with a Type-2 CP packet.
1582 ((char *)dev
->agp_buffer_map
->handle
1583 + buf
->offset
+ start
);
1584 data
[dwords
++] = RADEON_CP_PACKET2
;
1587 /* Fire off the indirect buffer */
1590 OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE
, 1));
1598 static void radeon_cp_dispatch_indices(struct drm_device
*dev
,
1599 struct drm_buf
* elt_buf
,
1600 drm_radeon_tcl_prim_t
* prim
)
1602 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1603 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1604 int offset
= dev_priv
->gart_buffers_offset
+ prim
->offset
;
1608 int start
= prim
->start
+ RADEON_INDEX_PRIM_OFFSET
;
1609 int count
= (prim
->finish
- start
) / sizeof(u16
);
1610 int nbox
= sarea_priv
->nbox
;
1612 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1615 prim
->start
, prim
->finish
, prim
->offset
, prim
->numverts
);
1617 if (bad_prim_vertex_nr(prim
->prim
, count
)) {
1618 DRM_ERROR("bad prim %x count %d\n", prim
->prim
, count
);
1622 if (start
>= prim
->finish
|| (prim
->start
& 0x7)) {
1623 DRM_ERROR("buffer prim %d\n", prim
->prim
);
1627 dwords
= (prim
->finish
- prim
->start
+ 3) / sizeof(u32
);
1629 data
= (u32
*) ((char *)dev
->agp_buffer_map
->handle
+
1630 elt_buf
->offset
+ prim
->start
);
1632 data
[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM
, dwords
- 2);
1634 data
[2] = prim
->numverts
;
1635 data
[3] = prim
->vc_format
;
1636 data
[4] = (prim
->prim
|
1637 RADEON_PRIM_WALK_IND
|
1638 RADEON_COLOR_ORDER_RGBA
|
1639 RADEON_VTX_FMT_RADEON_MODE
|
1640 (count
<< RADEON_NUM_VERTICES_SHIFT
));
1644 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1646 radeon_cp_dispatch_indirect(dev
, elt_buf
,
1647 prim
->start
, prim
->finish
);
1654 #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1656 static int radeon_cp_dispatch_texture(struct drm_device
* dev
,
1657 struct drm_file
*file_priv
,
1658 drm_radeon_texture_t
* tex
,
1659 drm_radeon_tex_image_t
* image
)
1661 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1662 struct drm_buf
*buf
;
1665 const u8 __user
*data
;
1666 int size
, dwords
, tex_width
, blit_width
, spitch
;
1669 u32 texpitch
, microtile
;
1670 u32 offset
, byte_offset
;
1673 if (radeon_check_and_fixup_offset(dev_priv
, file_priv
, &tex
->offset
)) {
1674 DRM_ERROR("Invalid destination offset\n");
1678 dev_priv
->stats
.boxes
|= RADEON_BOX_TEXTURE_LOAD
;
1680 /* Flush the pixel cache. This ensures no pixel data gets mixed
1681 * up with the texture data from the host data blit, otherwise
1682 * part of the texture image may be corrupted.
1685 RADEON_FLUSH_CACHE();
1686 RADEON_WAIT_UNTIL_IDLE();
1689 /* The compiler won't optimize away a division by a variable,
1690 * even if the only legal values are powers of two. Thus, we'll
1691 * use a shift instead.
1693 switch (tex
->format
) {
1694 case RADEON_TXFORMAT_ARGB8888
:
1695 case RADEON_TXFORMAT_RGBA8888
:
1696 format
= RADEON_COLOR_FORMAT_ARGB8888
;
1697 tex_width
= tex
->width
* 4;
1698 blit_width
= image
->width
* 4;
1700 case RADEON_TXFORMAT_AI88
:
1701 case RADEON_TXFORMAT_ARGB1555
:
1702 case RADEON_TXFORMAT_RGB565
:
1703 case RADEON_TXFORMAT_ARGB4444
:
1704 case RADEON_TXFORMAT_VYUY422
:
1705 case RADEON_TXFORMAT_YVYU422
:
1706 format
= RADEON_COLOR_FORMAT_RGB565
;
1707 tex_width
= tex
->width
* 2;
1708 blit_width
= image
->width
* 2;
1710 case RADEON_TXFORMAT_I8
:
1711 case RADEON_TXFORMAT_RGB332
:
1712 format
= RADEON_COLOR_FORMAT_CI8
;
1713 tex_width
= tex
->width
* 1;
1714 blit_width
= image
->width
* 1;
1717 DRM_ERROR("invalid texture format %d\n", tex
->format
);
1720 spitch
= blit_width
>> 6;
1721 if (spitch
== 0 && image
->height
> 1)
1724 texpitch
= tex
->pitch
;
1725 if ((texpitch
<< 22) & RADEON_DST_TILE_MICRO
) {
1727 if (tex_width
< 64) {
1728 texpitch
&= ~(RADEON_DST_TILE_MICRO
>> 22);
1729 /* we got tiled coordinates, untile them */
1735 /* this might fail for zero-sized uploads - are those illegal? */
1736 if (!radeon_check_offset(dev_priv
, tex
->offset
+ image
->height
*
1738 DRM_ERROR("Invalid final destination offset\n");
1742 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width
, tex
->height
, blit_width
);
1745 DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1746 tex
->offset
>> 10, tex
->pitch
, tex
->format
,
1747 image
->x
, image
->y
, image
->width
, image
->height
);
1749 /* Make a copy of some parameters in case we have to
1750 * update them for a multi-pass texture blit.
1752 height
= image
->height
;
1753 data
= (const u8 __user
*)image
->data
;
1755 size
= height
* blit_width
;
1757 if (size
> RADEON_MAX_TEXTURE_SIZE
) {
1758 height
= RADEON_MAX_TEXTURE_SIZE
/ blit_width
;
1759 size
= height
* blit_width
;
1760 } else if (size
< 4 && size
> 0) {
1762 } else if (size
== 0) {
1766 buf
= radeon_freelist_get(dev
);
1768 radeon_do_cp_idle(dev_priv
);
1769 buf
= radeon_freelist_get(dev
);
1772 DRM_DEBUG("EAGAIN\n");
1773 if (DRM_COPY_TO_USER(tex
->image
, image
, sizeof(*image
)))
1778 /* Dispatch the indirect buffer.
1781 (u32
*) ((char *)dev
->agp_buffer_map
->handle
+ buf
->offset
);
1784 #define RADEON_COPY_MT(_buf, _data, _width) \
1786 if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1787 DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
1793 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
1794 however, we cannot use blitter directly for texture width < 64 bytes,
1795 since minimum tex pitch is 64 bytes and we need this to match
1796 the texture width, otherwise the blitter will tile it wrong.
1797 Thus, tiling manually in this case. Additionally, need to special
1798 case tex height = 1, since our actual image will have height 2
1799 and we need to ensure we don't read beyond the texture size
1801 if (tex
->height
== 1) {
1802 if (tex_width
>= 64 || tex_width
<= 16) {
1803 RADEON_COPY_MT(buffer
, data
,
1804 (int)(tex_width
* sizeof(u32
)));
1805 } else if (tex_width
== 32) {
1806 RADEON_COPY_MT(buffer
, data
, 16);
1807 RADEON_COPY_MT(buffer
+ 8,
1810 } else if (tex_width
>= 64 || tex_width
== 16) {
1811 RADEON_COPY_MT(buffer
, data
,
1812 (int)(dwords
* sizeof(u32
)));
1813 } else if (tex_width
< 16) {
1814 for (i
= 0; i
< tex
->height
; i
++) {
1815 RADEON_COPY_MT(buffer
, data
, tex_width
);
1819 } else if (tex_width
== 32) {
1820 /* TODO: make sure this works when not fitting in one buffer
1821 (i.e. 32bytes x 2048...) */
1822 for (i
= 0; i
< tex
->height
; i
+= 2) {
1823 RADEON_COPY_MT(buffer
, data
, 16);
1825 RADEON_COPY_MT(buffer
+ 8, data
, 16);
1827 RADEON_COPY_MT(buffer
+ 4, data
, 16);
1829 RADEON_COPY_MT(buffer
+ 12, data
, 16);
1835 if (tex_width
>= 32) {
1836 /* Texture image width is larger than the minimum, so we
1837 * can upload it directly.
1839 RADEON_COPY_MT(buffer
, data
,
1840 (int)(dwords
* sizeof(u32
)));
1842 /* Texture image width is less than the minimum, so we
1843 * need to pad out each image scanline to the minimum
1846 for (i
= 0; i
< tex
->height
; i
++) {
1847 RADEON_COPY_MT(buffer
, data
, tex_width
);
1854 #undef RADEON_COPY_MT
1855 byte_offset
= (image
->y
& ~2047) * blit_width
;
1856 buf
->file_priv
= file_priv
;
1858 offset
= dev_priv
->gart_buffers_offset
+ buf
->offset
;
1860 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI
, 5));
1861 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
1862 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1863 RADEON_GMC_BRUSH_NONE
|
1865 RADEON_GMC_SRC_DATATYPE_COLOR
|
1867 RADEON_DP_SRC_SOURCE_MEMORY
|
1868 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
1869 OUT_RING((spitch
<< 22) | (offset
>> 10));
1870 OUT_RING((texpitch
<< 22) | ((tex
->offset
>> 10) + (byte_offset
>> 10)));
1872 OUT_RING((image
->x
<< 16) | (image
->y
% 2048));
1873 OUT_RING((image
->width
<< 16) | height
);
1874 RADEON_WAIT_UNTIL_2D_IDLE();
1878 radeon_cp_discard_buffer(dev
, buf
);
1880 /* Update the input parameters for next time */
1882 image
->height
-= height
;
1883 image
->data
= (const u8 __user
*)image
->data
+ size
;
1884 } while (image
->height
> 0);
1886 /* Flush the pixel cache after the blit completes. This ensures
1887 * the texture data is written out to memory before rendering
1891 RADEON_FLUSH_CACHE();
1892 RADEON_WAIT_UNTIL_2D_IDLE();
1899 static void radeon_cp_dispatch_stipple(struct drm_device
* dev
, u32
* stipple
)
1901 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1908 OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR
, 0));
1909 OUT_RING(0x00000000);
1911 OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA
, 31));
1912 for (i
= 0; i
< 32; i
++) {
1913 OUT_RING(stipple
[i
]);
1919 static void radeon_apply_surface_regs(int surf_index
,
1920 drm_radeon_private_t
*dev_priv
)
1922 if (!dev_priv
->mmio
)
1925 radeon_do_cp_idle(dev_priv
);
1927 RADEON_WRITE(RADEON_SURFACE0_INFO
+ 16 * surf_index
,
1928 dev_priv
->surfaces
[surf_index
].flags
);
1929 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND
+ 16 * surf_index
,
1930 dev_priv
->surfaces
[surf_index
].lower
);
1931 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND
+ 16 * surf_index
,
1932 dev_priv
->surfaces
[surf_index
].upper
);
1935 /* Allocates a virtual surface
1936 * doesn't always allocate a real surface, will stretch an existing
1937 * surface when possible.
1939 * Note that refcount can be at most 2, since during a free refcount=3
1940 * might mean we have to allocate a new surface which might not always
1942 * For example : we allocate three contigous surfaces ABC. If B is
1943 * freed, we suddenly need two surfaces to store A and C, which might
1944 * not always be available.
1946 static int alloc_surface(drm_radeon_surface_alloc_t
*new,
1947 drm_radeon_private_t
*dev_priv
,
1948 struct drm_file
*file_priv
)
1950 struct radeon_virt_surface
*s
;
1952 int virt_surface_index
;
1953 uint32_t new_upper
, new_lower
;
1955 new_lower
= new->address
;
1956 new_upper
= new_lower
+ new->size
- 1;
1959 if ((new_lower
>= new_upper
) || (new->flags
== 0) || (new->size
== 0) ||
1960 ((new_upper
& RADEON_SURF_ADDRESS_FIXED_MASK
) !=
1961 RADEON_SURF_ADDRESS_FIXED_MASK
)
1962 || ((new_lower
& RADEON_SURF_ADDRESS_FIXED_MASK
) != 0))
1965 /* make sure there is no overlap with existing surfaces */
1966 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
1967 if ((dev_priv
->surfaces
[i
].refcount
!= 0) &&
1968 (((new_lower
>= dev_priv
->surfaces
[i
].lower
) &&
1969 (new_lower
< dev_priv
->surfaces
[i
].upper
)) ||
1970 ((new_lower
< dev_priv
->surfaces
[i
].lower
) &&
1971 (new_upper
> dev_priv
->surfaces
[i
].lower
)))) {
1976 /* find a virtual surface */
1977 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++)
1978 if (dev_priv
->virt_surfaces
[i
].file_priv
== 0)
1980 if (i
== 2 * RADEON_MAX_SURFACES
) {
1983 virt_surface_index
= i
;
1985 /* try to reuse an existing surface */
1986 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
1988 if ((dev_priv
->surfaces
[i
].refcount
== 1) &&
1989 (new->flags
== dev_priv
->surfaces
[i
].flags
) &&
1990 (new_upper
+ 1 == dev_priv
->surfaces
[i
].lower
)) {
1991 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
1992 s
->surface_index
= i
;
1993 s
->lower
= new_lower
;
1994 s
->upper
= new_upper
;
1995 s
->flags
= new->flags
;
1996 s
->file_priv
= file_priv
;
1997 dev_priv
->surfaces
[i
].refcount
++;
1998 dev_priv
->surfaces
[i
].lower
= s
->lower
;
1999 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
2000 return virt_surface_index
;
2004 if ((dev_priv
->surfaces
[i
].refcount
== 1) &&
2005 (new->flags
== dev_priv
->surfaces
[i
].flags
) &&
2006 (new_lower
== dev_priv
->surfaces
[i
].upper
+ 1)) {
2007 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
2008 s
->surface_index
= i
;
2009 s
->lower
= new_lower
;
2010 s
->upper
= new_upper
;
2011 s
->flags
= new->flags
;
2012 s
->file_priv
= file_priv
;
2013 dev_priv
->surfaces
[i
].refcount
++;
2014 dev_priv
->surfaces
[i
].upper
= s
->upper
;
2015 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
2016 return virt_surface_index
;
2020 /* okay, we need a new one */
2021 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
2022 if (dev_priv
->surfaces
[i
].refcount
== 0) {
2023 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
2024 s
->surface_index
= i
;
2025 s
->lower
= new_lower
;
2026 s
->upper
= new_upper
;
2027 s
->flags
= new->flags
;
2028 s
->file_priv
= file_priv
;
2029 dev_priv
->surfaces
[i
].refcount
= 1;
2030 dev_priv
->surfaces
[i
].lower
= s
->lower
;
2031 dev_priv
->surfaces
[i
].upper
= s
->upper
;
2032 dev_priv
->surfaces
[i
].flags
= s
->flags
;
2033 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
2034 return virt_surface_index
;
2038 /* we didn't find anything */
2042 static int free_surface(struct drm_file
*file_priv
,
2043 drm_radeon_private_t
* dev_priv
,
2046 struct radeon_virt_surface
*s
;
2048 /* find the virtual surface */
2049 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++) {
2050 s
= &(dev_priv
->virt_surfaces
[i
]);
2052 if ((lower
== s
->lower
) && (file_priv
== s
->file_priv
))
2054 if (dev_priv
->surfaces
[s
->surface_index
].
2056 dev_priv
->surfaces
[s
->surface_index
].
2059 if (dev_priv
->surfaces
[s
->surface_index
].
2061 dev_priv
->surfaces
[s
->surface_index
].
2064 dev_priv
->surfaces
[s
->surface_index
].refcount
--;
2065 if (dev_priv
->surfaces
[s
->surface_index
].
2067 dev_priv
->surfaces
[s
->surface_index
].
2069 s
->file_priv
= NULL
;
2070 radeon_apply_surface_regs(s
->surface_index
,
2079 static void radeon_surfaces_release(struct drm_file
*file_priv
,
2080 drm_radeon_private_t
* dev_priv
)
2083 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++) {
2084 if (dev_priv
->virt_surfaces
[i
].file_priv
== file_priv
)
2085 free_surface(file_priv
, dev_priv
,
2086 dev_priv
->virt_surfaces
[i
].lower
);
2090 /* ================================================================
2093 static int radeon_surface_alloc(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2095 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2096 drm_radeon_surface_alloc_t
*alloc
= data
;
2098 if (alloc_surface(alloc
, dev_priv
, file_priv
) == -1)
2104 static int radeon_surface_free(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2106 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2107 drm_radeon_surface_free_t
*memfree
= data
;
2109 if (free_surface(file_priv
, dev_priv
, memfree
->address
))
2115 static int radeon_cp_clear(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2117 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2118 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2119 drm_radeon_clear_t
*clear
= data
;
2120 drm_radeon_clear_rect_t depth_boxes
[RADEON_NR_SAREA_CLIPRECTS
];
2123 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2125 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2127 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2128 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
2130 if (DRM_COPY_FROM_USER(&depth_boxes
, clear
->depth_boxes
,
2131 sarea_priv
->nbox
* sizeof(depth_boxes
[0])))
2134 radeon_cp_dispatch_clear(dev
, clear
, depth_boxes
);
2140 /* Not sure why this isn't set all the time:
2142 static int radeon_do_init_pageflip(struct drm_device
*dev
)
2144 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2150 RADEON_WAIT_UNTIL_3D_IDLE();
2151 OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL
, 0));
2152 OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL
) |
2153 RADEON_CRTC_OFFSET_FLIP_CNTL
);
2154 OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL
, 0));
2155 OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL
) |
2156 RADEON_CRTC_OFFSET_FLIP_CNTL
);
2159 dev_priv
->page_flipping
= 1;
2161 if (dev_priv
->sarea_priv
->pfCurrentPage
!= 1)
2162 dev_priv
->sarea_priv
->pfCurrentPage
= 0;
2167 /* Swapping and flipping are different operations, need different ioctls.
2168 * They can & should be intermixed to support multiple 3d windows.
2170 static int radeon_cp_flip(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2172 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2175 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2177 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2179 if (!dev_priv
->page_flipping
)
2180 radeon_do_init_pageflip(dev
);
2182 radeon_cp_dispatch_flip(dev
);
2188 static int radeon_cp_swap(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2190 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2191 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2195 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2197 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2199 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2200 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
2202 radeon_cp_dispatch_swap(dev
);
2203 sarea_priv
->ctx_owner
= 0;
2209 static int radeon_cp_vertex(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2211 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2212 drm_radeon_sarea_t
*sarea_priv
;
2213 struct drm_device_dma
*dma
= dev
->dma
;
2214 struct drm_buf
*buf
;
2215 drm_radeon_vertex_t
*vertex
= data
;
2216 drm_radeon_tcl_prim_t prim
;
2218 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2220 sarea_priv
= dev_priv
->sarea_priv
;
2222 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2223 DRM_CURRENTPID
, vertex
->idx
, vertex
->count
, vertex
->discard
);
2225 if (vertex
->idx
< 0 || vertex
->idx
>= dma
->buf_count
) {
2226 DRM_ERROR("buffer index %d (of %d max)\n",
2227 vertex
->idx
, dma
->buf_count
- 1);
2230 if (vertex
->prim
< 0 || vertex
->prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
2231 DRM_ERROR("buffer prim %d\n", vertex
->prim
);
2235 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2236 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2238 buf
= dma
->buflist
[vertex
->idx
];
2240 if (buf
->file_priv
!= file_priv
) {
2241 DRM_ERROR("process %d using buffer owned by %p\n",
2242 DRM_CURRENTPID
, buf
->file_priv
);
2246 DRM_ERROR("sending pending buffer %d\n", vertex
->idx
);
2250 /* Build up a prim_t record:
2252 if (vertex
->count
) {
2253 buf
->used
= vertex
->count
; /* not used? */
2255 if (sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
2256 if (radeon_emit_state(dev_priv
, file_priv
,
2257 &sarea_priv
->context_state
,
2258 sarea_priv
->tex_state
,
2259 sarea_priv
->dirty
)) {
2260 DRM_ERROR("radeon_emit_state failed\n");
2264 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
2265 RADEON_UPLOAD_TEX1IMAGES
|
2266 RADEON_UPLOAD_TEX2IMAGES
|
2267 RADEON_REQUIRE_QUIESCENCE
);
2271 prim
.finish
= vertex
->count
; /* unused */
2272 prim
.prim
= vertex
->prim
;
2273 prim
.numverts
= vertex
->count
;
2274 prim
.vc_format
= sarea_priv
->vc_format
;
2276 radeon_cp_dispatch_vertex(dev
, buf
, &prim
);
2279 if (vertex
->discard
) {
2280 radeon_cp_discard_buffer(dev
, buf
);
2287 static int radeon_cp_indices(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2289 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2290 drm_radeon_sarea_t
*sarea_priv
;
2291 struct drm_device_dma
*dma
= dev
->dma
;
2292 struct drm_buf
*buf
;
2293 drm_radeon_indices_t
*elts
= data
;
2294 drm_radeon_tcl_prim_t prim
;
2297 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2299 sarea_priv
= dev_priv
->sarea_priv
;
2301 DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2302 DRM_CURRENTPID
, elts
->idx
, elts
->start
, elts
->end
,
2305 if (elts
->idx
< 0 || elts
->idx
>= dma
->buf_count
) {
2306 DRM_ERROR("buffer index %d (of %d max)\n",
2307 elts
->idx
, dma
->buf_count
- 1);
2310 if (elts
->prim
< 0 || elts
->prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
2311 DRM_ERROR("buffer prim %d\n", elts
->prim
);
2315 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2316 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2318 buf
= dma
->buflist
[elts
->idx
];
2320 if (buf
->file_priv
!= file_priv
) {
2321 DRM_ERROR("process %d using buffer owned by %p\n",
2322 DRM_CURRENTPID
, buf
->file_priv
);
2326 DRM_ERROR("sending pending buffer %d\n", elts
->idx
);
2330 count
= (elts
->end
- elts
->start
) / sizeof(u16
);
2331 elts
->start
-= RADEON_INDEX_PRIM_OFFSET
;
2333 if (elts
->start
& 0x7) {
2334 DRM_ERROR("misaligned buffer 0x%x\n", elts
->start
);
2337 if (elts
->start
< buf
->used
) {
2338 DRM_ERROR("no header 0x%x - 0x%x\n", elts
->start
, buf
->used
);
2342 buf
->used
= elts
->end
;
2344 if (sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
2345 if (radeon_emit_state(dev_priv
, file_priv
,
2346 &sarea_priv
->context_state
,
2347 sarea_priv
->tex_state
,
2348 sarea_priv
->dirty
)) {
2349 DRM_ERROR("radeon_emit_state failed\n");
2353 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
2354 RADEON_UPLOAD_TEX1IMAGES
|
2355 RADEON_UPLOAD_TEX2IMAGES
|
2356 RADEON_REQUIRE_QUIESCENCE
);
2359 /* Build up a prim_t record:
2361 prim
.start
= elts
->start
;
2362 prim
.finish
= elts
->end
;
2363 prim
.prim
= elts
->prim
;
2364 prim
.offset
= 0; /* offset from start of dma buffers */
2365 prim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
2366 prim
.vc_format
= sarea_priv
->vc_format
;
2368 radeon_cp_dispatch_indices(dev
, buf
, &prim
);
2369 if (elts
->discard
) {
2370 radeon_cp_discard_buffer(dev
, buf
);
2377 static int radeon_cp_texture(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2379 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2380 drm_radeon_texture_t
*tex
= data
;
2381 drm_radeon_tex_image_t image
;
2384 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2386 if (tex
->image
== NULL
) {
2387 DRM_ERROR("null texture image!\n");
2391 if (DRM_COPY_FROM_USER(&image
,
2392 (drm_radeon_tex_image_t __user
*) tex
->image
,
2396 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2397 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2399 ret
= radeon_cp_dispatch_texture(dev
, file_priv
, tex
, &image
);
2404 static int radeon_cp_stipple(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2406 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2407 drm_radeon_stipple_t
*stipple
= data
;
2410 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2412 if (DRM_COPY_FROM_USER(&mask
, stipple
->mask
, 32 * sizeof(u32
)))
2415 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2417 radeon_cp_dispatch_stipple(dev
, mask
);
2423 static int radeon_cp_indirect(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2425 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2426 struct drm_device_dma
*dma
= dev
->dma
;
2427 struct drm_buf
*buf
;
2428 drm_radeon_indirect_t
*indirect
= data
;
2431 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2434 DRM_ERROR("called with no initialization\n");
2438 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
2439 indirect
->idx
, indirect
->start
, indirect
->end
,
2442 if (indirect
->idx
< 0 || indirect
->idx
>= dma
->buf_count
) {
2443 DRM_ERROR("buffer index %d (of %d max)\n",
2444 indirect
->idx
, dma
->buf_count
- 1);
2448 buf
= dma
->buflist
[indirect
->idx
];
2450 if (buf
->file_priv
!= file_priv
) {
2451 DRM_ERROR("process %d using buffer owned by %p\n",
2452 DRM_CURRENTPID
, buf
->file_priv
);
2456 DRM_ERROR("sending pending buffer %d\n", indirect
->idx
);
2460 if (indirect
->start
< buf
->used
) {
2461 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2462 indirect
->start
, buf
->used
);
2466 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2467 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2469 buf
->used
= indirect
->end
;
2471 /* Dispatch the indirect buffer full of commands from the
2472 * X server. This is insecure and is thus only available to
2473 * privileged clients.
2475 if ((dev_priv
->flags
& RADEON_FAMILY_MASK
) >= CHIP_R600
)
2476 r600_cp_dispatch_indirect(dev
, buf
, indirect
->start
, indirect
->end
);
2478 /* Wait for the 3D stream to idle before the indirect buffer
2479 * containing 2D acceleration commands is processed.
2482 RADEON_WAIT_UNTIL_3D_IDLE();
2484 radeon_cp_dispatch_indirect(dev
, buf
, indirect
->start
, indirect
->end
);
2487 if (indirect
->discard
)
2488 radeon_cp_discard_buffer(dev
, buf
);
2494 static int radeon_cp_vertex2(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2496 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2497 drm_radeon_sarea_t
*sarea_priv
;
2498 struct drm_device_dma
*dma
= dev
->dma
;
2499 struct drm_buf
*buf
;
2500 drm_radeon_vertex2_t
*vertex
= data
;
2502 unsigned char laststate
;
2504 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2506 sarea_priv
= dev_priv
->sarea_priv
;
2508 DRM_DEBUG("pid=%d index=%d discard=%d\n",
2509 DRM_CURRENTPID
, vertex
->idx
, vertex
->discard
);
2511 if (vertex
->idx
< 0 || vertex
->idx
>= dma
->buf_count
) {
2512 DRM_ERROR("buffer index %d (of %d max)\n",
2513 vertex
->idx
, dma
->buf_count
- 1);
2517 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2518 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2520 buf
= dma
->buflist
[vertex
->idx
];
2522 if (buf
->file_priv
!= file_priv
) {
2523 DRM_ERROR("process %d using buffer owned by %p\n",
2524 DRM_CURRENTPID
, buf
->file_priv
);
2529 DRM_ERROR("sending pending buffer %d\n", vertex
->idx
);
2533 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2536 for (laststate
= 0xff, i
= 0; i
< vertex
->nr_prims
; i
++) {
2537 drm_radeon_prim_t prim
;
2538 drm_radeon_tcl_prim_t tclprim
;
2540 if (DRM_COPY_FROM_USER(&prim
, &vertex
->prim
[i
], sizeof(prim
)))
2543 if (prim
.stateidx
!= laststate
) {
2544 drm_radeon_state_t state
;
2546 if (DRM_COPY_FROM_USER(&state
,
2547 &vertex
->state
[prim
.stateidx
],
2551 if (radeon_emit_state2(dev_priv
, file_priv
, &state
)) {
2552 DRM_ERROR("radeon_emit_state2 failed\n");
2556 laststate
= prim
.stateidx
;
2559 tclprim
.start
= prim
.start
;
2560 tclprim
.finish
= prim
.finish
;
2561 tclprim
.prim
= prim
.prim
;
2562 tclprim
.vc_format
= prim
.vc_format
;
2564 if (prim
.prim
& RADEON_PRIM_WALK_IND
) {
2565 tclprim
.offset
= prim
.numverts
* 64;
2566 tclprim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
2568 radeon_cp_dispatch_indices(dev
, buf
, &tclprim
);
2570 tclprim
.numverts
= prim
.numverts
;
2571 tclprim
.offset
= 0; /* not used */
2573 radeon_cp_dispatch_vertex(dev
, buf
, &tclprim
);
2576 if (sarea_priv
->nbox
== 1)
2577 sarea_priv
->nbox
= 0;
2580 if (vertex
->discard
) {
2581 radeon_cp_discard_buffer(dev
, buf
);
2588 static int radeon_emit_packets(drm_radeon_private_t
* dev_priv
,
2589 struct drm_file
*file_priv
,
2590 drm_radeon_cmd_header_t header
,
2591 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2593 int id
= (int)header
.packet
.packet_id
;
2595 int *data
= (int *)cmdbuf
->buf
;
2598 if (id
>= RADEON_MAX_STATE_PACKETS
)
2601 sz
= packet
[id
].len
;
2602 reg
= packet
[id
].start
;
2604 if (sz
* sizeof(int) > cmdbuf
->bufsz
) {
2605 DRM_ERROR("Packet size provided larger than data provided\n");
2609 if (radeon_check_and_fixup_packets(dev_priv
, file_priv
, id
, data
)) {
2610 DRM_ERROR("Packet verification failed\n");
2615 OUT_RING(CP_PACKET0(reg
, (sz
- 1)));
2616 OUT_RING_TABLE(data
, sz
);
2619 cmdbuf
->buf
+= sz
* sizeof(int);
2620 cmdbuf
->bufsz
-= sz
* sizeof(int);
2624 static __inline__
int radeon_emit_scalars(drm_radeon_private_t
*dev_priv
,
2625 drm_radeon_cmd_header_t header
,
2626 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2628 int sz
= header
.scalars
.count
;
2629 int start
= header
.scalars
.offset
;
2630 int stride
= header
.scalars
.stride
;
2634 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG
, 0));
2635 OUT_RING(start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
2636 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG
, sz
- 1));
2637 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2639 cmdbuf
->buf
+= sz
* sizeof(int);
2640 cmdbuf
->bufsz
-= sz
* sizeof(int);
2646 static __inline__
int radeon_emit_scalars2(drm_radeon_private_t
*dev_priv
,
2647 drm_radeon_cmd_header_t header
,
2648 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2650 int sz
= header
.scalars
.count
;
2651 int start
= ((unsigned int)header
.scalars
.offset
) + 0x100;
2652 int stride
= header
.scalars
.stride
;
2656 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG
, 0));
2657 OUT_RING(start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
2658 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG
, sz
- 1));
2659 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2661 cmdbuf
->buf
+= sz
* sizeof(int);
2662 cmdbuf
->bufsz
-= sz
* sizeof(int);
2666 static __inline__
int radeon_emit_vectors(drm_radeon_private_t
*dev_priv
,
2667 drm_radeon_cmd_header_t header
,
2668 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2670 int sz
= header
.vectors
.count
;
2671 int start
= header
.vectors
.offset
;
2672 int stride
= header
.vectors
.stride
;
2676 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH
, 0);
2677 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG
, 0));
2678 OUT_RING(start
| (stride
<< RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT
));
2679 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG
, (sz
- 1)));
2680 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2683 cmdbuf
->buf
+= sz
* sizeof(int);
2684 cmdbuf
->bufsz
-= sz
* sizeof(int);
2688 static __inline__
int radeon_emit_veclinear(drm_radeon_private_t
*dev_priv
,
2689 drm_radeon_cmd_header_t header
,
2690 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2692 int sz
= header
.veclinear
.count
* 4;
2693 int start
= header
.veclinear
.addr_lo
| (header
.veclinear
.addr_hi
<< 8);
2698 if (sz
* 4 > cmdbuf
->bufsz
)
2702 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH
, 0);
2703 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG
, 0));
2704 OUT_RING(start
| (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT
));
2705 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG
, (sz
- 1)));
2706 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2709 cmdbuf
->buf
+= sz
* sizeof(int);
2710 cmdbuf
->bufsz
-= sz
* sizeof(int);
2714 static int radeon_emit_packet3(struct drm_device
* dev
,
2715 struct drm_file
*file_priv
,
2716 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2718 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2725 if ((ret
= radeon_check_and_fixup_packet3(dev_priv
, file_priv
,
2727 DRM_ERROR("Packet verification failed\n");
2732 OUT_RING_TABLE(cmdbuf
->buf
, cmdsz
);
2735 cmdbuf
->buf
+= cmdsz
* 4;
2736 cmdbuf
->bufsz
-= cmdsz
* 4;
2740 static int radeon_emit_packet3_cliprect(struct drm_device
*dev
,
2741 struct drm_file
*file_priv
,
2742 drm_radeon_kcmd_buffer_t
*cmdbuf
,
2745 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2746 struct drm_clip_rect box
;
2749 struct drm_clip_rect __user
*boxes
= cmdbuf
->boxes
;
2755 if ((ret
= radeon_check_and_fixup_packet3(dev_priv
, file_priv
,
2757 DRM_ERROR("Packet verification failed\n");
2765 if (i
< cmdbuf
->nbox
) {
2766 if (DRM_COPY_FROM_USER(&box
, &boxes
[i
], sizeof(box
)))
2768 /* FIXME The second and subsequent times round
2769 * this loop, send a WAIT_UNTIL_3D_IDLE before
2770 * calling emit_clip_rect(). This fixes a
2771 * lockup on fast machines when sending
2772 * several cliprects with a cmdbuf, as when
2773 * waving a 2D window over a 3D
2774 * window. Something in the commands from user
2775 * space seems to hang the card when they're
2776 * sent several times in a row. That would be
2777 * the correct place to fix it but this works
2778 * around it until I can figure that out - Tim
2782 RADEON_WAIT_UNTIL_3D_IDLE();
2785 radeon_emit_clip_rect(dev_priv
, &box
);
2789 OUT_RING_TABLE(cmdbuf
->buf
, cmdsz
);
2792 } while (++i
< cmdbuf
->nbox
);
2793 if (cmdbuf
->nbox
== 1)
2797 cmdbuf
->buf
+= cmdsz
* 4;
2798 cmdbuf
->bufsz
-= cmdsz
* 4;
2802 static int radeon_emit_wait(struct drm_device
* dev
, int flags
)
2804 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2807 DRM_DEBUG("%x\n", flags
);
2809 case RADEON_WAIT_2D
:
2811 RADEON_WAIT_UNTIL_2D_IDLE();
2814 case RADEON_WAIT_3D
:
2816 RADEON_WAIT_UNTIL_3D_IDLE();
2819 case RADEON_WAIT_2D
| RADEON_WAIT_3D
:
2821 RADEON_WAIT_UNTIL_IDLE();
2831 static int radeon_cp_cmdbuf(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2833 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2834 struct drm_device_dma
*dma
= dev
->dma
;
2835 struct drm_buf
*buf
= NULL
;
2837 drm_radeon_kcmd_buffer_t
*cmdbuf
= data
;
2838 drm_radeon_cmd_header_t header
;
2839 int orig_nbox
, orig_bufsz
;
2842 LOCK_TEST_WITH_RETURN(dev
, file_priv
);
2844 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2845 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2847 if (cmdbuf
->bufsz
> 64 * 1024 || cmdbuf
->bufsz
< 0) {
2851 /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid
2852 * races between checking values and using those values in other code,
2853 * and simply to avoid a lot of function calls to copy in data.
2855 orig_bufsz
= cmdbuf
->bufsz
;
2856 if (orig_bufsz
!= 0) {
2857 kbuf
= drm_alloc(cmdbuf
->bufsz
, DRM_MEM_DRIVER
);
2860 if (DRM_COPY_FROM_USER(kbuf
, (void __user
*)cmdbuf
->buf
,
2862 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2868 orig_nbox
= cmdbuf
->nbox
;
2870 if (dev_priv
->microcode_version
== UCODE_R300
) {
2872 temp
= r300_do_cp_cmdbuf(dev
, file_priv
, cmdbuf
);
2874 if (orig_bufsz
!= 0)
2875 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2880 /* microcode_version != r300 */
2881 while (cmdbuf
->bufsz
>= sizeof(header
)) {
2883 header
.i
= *(int *)cmdbuf
->buf
;
2884 cmdbuf
->buf
+= sizeof(header
);
2885 cmdbuf
->bufsz
-= sizeof(header
);
2887 switch (header
.header
.cmd_type
) {
2888 case RADEON_CMD_PACKET
:
2889 DRM_DEBUG("RADEON_CMD_PACKET\n");
2890 if (radeon_emit_packets
2891 (dev_priv
, file_priv
, header
, cmdbuf
)) {
2892 DRM_ERROR("radeon_emit_packets failed\n");
2897 case RADEON_CMD_SCALARS
:
2898 DRM_DEBUG("RADEON_CMD_SCALARS\n");
2899 if (radeon_emit_scalars(dev_priv
, header
, cmdbuf
)) {
2900 DRM_ERROR("radeon_emit_scalars failed\n");
2905 case RADEON_CMD_VECTORS
:
2906 DRM_DEBUG("RADEON_CMD_VECTORS\n");
2907 if (radeon_emit_vectors(dev_priv
, header
, cmdbuf
)) {
2908 DRM_ERROR("radeon_emit_vectors failed\n");
2913 case RADEON_CMD_DMA_DISCARD
:
2914 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2915 idx
= header
.dma
.buf_idx
;
2916 if (idx
< 0 || idx
>= dma
->buf_count
) {
2917 DRM_ERROR("buffer index %d (of %d max)\n",
2918 idx
, dma
->buf_count
- 1);
2922 buf
= dma
->buflist
[idx
];
2923 if (buf
->file_priv
!= file_priv
|| buf
->pending
) {
2924 DRM_ERROR("bad buffer %p %p %d\n",
2925 buf
->file_priv
, file_priv
,
2930 radeon_cp_discard_buffer(dev
, buf
);
2933 case RADEON_CMD_PACKET3
:
2934 DRM_DEBUG("RADEON_CMD_PACKET3\n");
2935 if (radeon_emit_packet3(dev
, file_priv
, cmdbuf
)) {
2936 DRM_ERROR("radeon_emit_packet3 failed\n");
2941 case RADEON_CMD_PACKET3_CLIP
:
2942 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2943 if (radeon_emit_packet3_cliprect
2944 (dev
, file_priv
, cmdbuf
, orig_nbox
)) {
2945 DRM_ERROR("radeon_emit_packet3_clip failed\n");
2950 case RADEON_CMD_SCALARS2
:
2951 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2952 if (radeon_emit_scalars2(dev_priv
, header
, cmdbuf
)) {
2953 DRM_ERROR("radeon_emit_scalars2 failed\n");
2958 case RADEON_CMD_WAIT
:
2959 DRM_DEBUG("RADEON_CMD_WAIT\n");
2960 if (radeon_emit_wait(dev
, header
.wait
.flags
)) {
2961 DRM_ERROR("radeon_emit_wait failed\n");
2965 case RADEON_CMD_VECLINEAR
:
2966 DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
2967 if (radeon_emit_veclinear(dev_priv
, header
, cmdbuf
)) {
2968 DRM_ERROR("radeon_emit_veclinear failed\n");
2974 DRM_ERROR("bad cmd_type %d at %p\n",
2975 header
.header
.cmd_type
,
2976 cmdbuf
->buf
- sizeof(header
));
2981 if (orig_bufsz
!= 0)
2982 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2984 DRM_DEBUG("DONE\n");
2989 if (orig_bufsz
!= 0)
2990 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2994 static int radeon_cp_getparam(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
2996 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2997 drm_radeon_getparam_t
*param
= data
;
3000 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID
);
3002 switch (param
->param
) {
3003 case RADEON_PARAM_GART_BUFFER_OFFSET
:
3004 value
= dev_priv
->gart_buffers_offset
;
3006 case RADEON_PARAM_LAST_FRAME
:
3007 dev_priv
->stats
.last_frame_reads
++;
3008 value
= GET_SCRATCH(dev_priv
, 0);
3010 case RADEON_PARAM_LAST_DISPATCH
:
3011 value
= GET_SCRATCH(dev_priv
, 1);
3013 case RADEON_PARAM_LAST_CLEAR
:
3014 dev_priv
->stats
.last_clear_reads
++;
3015 value
= GET_SCRATCH(dev_priv
, 2);
3017 case RADEON_PARAM_IRQ_NR
:
3020 case RADEON_PARAM_GART_BASE
:
3021 value
= dev_priv
->gart_vm_start
;
3023 case RADEON_PARAM_REGISTER_HANDLE
:
3024 value
= dev_priv
->mmio
->offset
;
3026 case RADEON_PARAM_STATUS_HANDLE
:
3027 value
= dev_priv
->ring_rptr_offset
;
3031 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
3032 * pointer which can't fit into an int-sized variable. According to
3033 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
3034 * not supporting it shouldn't be a problem. If the same functionality
3035 * is needed on 64-bit platforms, a new ioctl() would have to be added,
3036 * so backwards-compatibility for the embedded platforms can be
3037 * maintained. --davidm 4-Feb-2004.
3039 case RADEON_PARAM_SAREA_HANDLE
:
3040 /* The lock is the first dword in the sarea. */
3041 value
= (long)dev
->lock
.hw_lock
;
3044 case RADEON_PARAM_GART_TEX_HANDLE
:
3045 value
= dev_priv
->gart_textures_offset
;
3047 case RADEON_PARAM_SCRATCH_OFFSET
:
3048 if (!dev_priv
->writeback_works
)
3050 if ((dev_priv
->flags
& RADEON_FAMILY_MASK
) >= CHIP_R600
)
3051 value
= R600_SCRATCH_REG_OFFSET
;
3053 value
= RADEON_SCRATCH_REG_OFFSET
;
3055 case RADEON_PARAM_CARD_TYPE
:
3056 if (dev_priv
->flags
& RADEON_IS_PCIE
)
3057 value
= RADEON_CARD_PCIE
;
3058 else if (dev_priv
->flags
& RADEON_IS_AGP
)
3059 value
= RADEON_CARD_AGP
;
3061 value
= RADEON_CARD_PCI
;
3063 case RADEON_PARAM_VBLANK_CRTC
:
3064 value
= radeon_vblank_crtc_get(dev
);
3066 case RADEON_PARAM_FB_LOCATION
:
3067 value
= radeon_read_fb_location(dev_priv
);
3069 case RADEON_PARAM_NUM_GB_PIPES
:
3070 value
= dev_priv
->num_gb_pipes
;
3073 DRM_DEBUG("Invalid parameter %d\n", param
->param
);
3077 if (DRM_COPY_TO_USER(param
->value
, &value
, sizeof(int))) {
3078 DRM_ERROR("copy_to_user\n");
3085 static int radeon_cp_setparam(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
3087 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3088 drm_radeon_setparam_t
*sp
= data
;
3089 struct drm_radeon_driver_file_fields
*radeon_priv
;
3091 switch (sp
->param
) {
3092 case RADEON_SETPARAM_FB_LOCATION
:
3093 radeon_priv
= file_priv
->driver_priv
;
3094 radeon_priv
->radeon_fb_delta
= dev_priv
->fb_location
-
3097 case RADEON_SETPARAM_SWITCH_TILING
:
3098 if (sp
->value
== 0) {
3099 DRM_DEBUG("color tiling disabled\n");
3100 dev_priv
->front_pitch_offset
&= ~RADEON_DST_TILE_MACRO
;
3101 dev_priv
->back_pitch_offset
&= ~RADEON_DST_TILE_MACRO
;
3102 if (dev_priv
->sarea_priv
)
3103 dev_priv
->sarea_priv
->tiling_enabled
= 0;
3104 } else if (sp
->value
== 1) {
3105 DRM_DEBUG("color tiling enabled\n");
3106 dev_priv
->front_pitch_offset
|= RADEON_DST_TILE_MACRO
;
3107 dev_priv
->back_pitch_offset
|= RADEON_DST_TILE_MACRO
;
3108 if (dev_priv
->sarea_priv
)
3109 dev_priv
->sarea_priv
->tiling_enabled
= 1;
3112 case RADEON_SETPARAM_PCIGART_LOCATION
:
3113 dev_priv
->pcigart_offset
= sp
->value
;
3114 dev_priv
->pcigart_offset_set
= 1;
3116 case RADEON_SETPARAM_NEW_MEMMAP
:
3117 dev_priv
->new_memmap
= sp
->value
;
3119 case RADEON_SETPARAM_PCIGART_TABLE_SIZE
:
3120 dev_priv
->gart_info
.table_size
= sp
->value
;
3121 if (dev_priv
->gart_info
.table_size
< RADEON_PCIGART_TABLE_SIZE
)
3122 dev_priv
->gart_info
.table_size
= RADEON_PCIGART_TABLE_SIZE
;
3124 case RADEON_SETPARAM_VBLANK_CRTC
:
3125 return radeon_vblank_crtc_set(dev
, sp
->value
);
3128 DRM_DEBUG("Invalid parameter %d\n", sp
->param
);
3135 /* When a client dies:
3136 * - Check for and clean up flipped page state
3137 * - Free any alloced GART memory.
3138 * - Free any alloced radeon surfaces.
3140 * DRM infrastructure takes care of reclaiming dma buffers.
3142 void radeon_driver_preclose(struct drm_device
*dev
, struct drm_file
*file_priv
)
3144 if (dev
->dev_private
) {
3145 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3146 dev_priv
->page_flipping
= 0;
3147 radeon_mem_release(file_priv
, dev_priv
->gart_heap
);
3148 radeon_mem_release(file_priv
, dev_priv
->fb_heap
);
3149 radeon_surfaces_release(file_priv
, dev_priv
);
3153 void radeon_driver_lastclose(struct drm_device
*dev
)
3155 radeon_surfaces_release(PCIGART_FILE_PRIV
, dev
->dev_private
);
3156 radeon_do_release(dev
);
3159 int radeon_driver_open(struct drm_device
*dev
, struct drm_file
*file_priv
)
3161 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3162 struct drm_radeon_driver_file_fields
*radeon_priv
;
3166 (struct drm_radeon_driver_file_fields
*)
3167 drm_alloc(sizeof(*radeon_priv
), DRM_MEM_FILES
);
3172 file_priv
->driver_priv
= radeon_priv
;
3175 radeon_priv
->radeon_fb_delta
= dev_priv
->fb_location
;
3177 radeon_priv
->radeon_fb_delta
= 0;
3181 void radeon_driver_postclose(struct drm_device
*dev
, struct drm_file
*file_priv
)
3183 struct drm_radeon_driver_file_fields
*radeon_priv
=
3184 file_priv
->driver_priv
;
3186 drm_free(radeon_priv
, sizeof(*radeon_priv
), DRM_MEM_FILES
);
3189 struct drm_ioctl_desc radeon_ioctls
[] = {
3190 DRM_IOCTL_DEF(DRM_RADEON_CP_INIT
, radeon_cp_init
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
3191 DRM_IOCTL_DEF(DRM_RADEON_CP_START
, radeon_cp_start
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
3192 DRM_IOCTL_DEF(DRM_RADEON_CP_STOP
, radeon_cp_stop
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
3193 DRM_IOCTL_DEF(DRM_RADEON_CP_RESET
, radeon_cp_reset
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
3194 DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE
, radeon_cp_idle
, DRM_AUTH
),
3195 DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME
, radeon_cp_resume
, DRM_AUTH
),
3196 DRM_IOCTL_DEF(DRM_RADEON_RESET
, radeon_engine_reset
, DRM_AUTH
),
3197 DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN
, radeon_fullscreen
, DRM_AUTH
),
3198 DRM_IOCTL_DEF(DRM_RADEON_SWAP
, radeon_cp_swap
, DRM_AUTH
),
3199 DRM_IOCTL_DEF(DRM_RADEON_CLEAR
, radeon_cp_clear
, DRM_AUTH
),
3200 DRM_IOCTL_DEF(DRM_RADEON_VERTEX
, radeon_cp_vertex
, DRM_AUTH
),
3201 DRM_IOCTL_DEF(DRM_RADEON_INDICES
, radeon_cp_indices
, DRM_AUTH
),
3202 DRM_IOCTL_DEF(DRM_RADEON_TEXTURE
, radeon_cp_texture
, DRM_AUTH
),
3203 DRM_IOCTL_DEF(DRM_RADEON_STIPPLE
, radeon_cp_stipple
, DRM_AUTH
),
3204 DRM_IOCTL_DEF(DRM_RADEON_INDIRECT
, radeon_cp_indirect
, DRM_AUTH
|DRM_ROOT_ONLY
),
3205 DRM_IOCTL_DEF(DRM_RADEON_VERTEX2
, radeon_cp_vertex2
, DRM_AUTH
),
3206 DRM_IOCTL_DEF(DRM_RADEON_CMDBUF
, radeon_cp_cmdbuf
, DRM_AUTH
),
3207 DRM_IOCTL_DEF(DRM_RADEON_GETPARAM
, radeon_cp_getparam
, DRM_AUTH
),
3208 DRM_IOCTL_DEF(DRM_RADEON_FLIP
, radeon_cp_flip
, DRM_AUTH
),
3209 DRM_IOCTL_DEF(DRM_RADEON_ALLOC
, radeon_mem_alloc
, DRM_AUTH
),
3210 DRM_IOCTL_DEF(DRM_RADEON_FREE
, radeon_mem_free
, DRM_AUTH
),
3211 DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP
, radeon_mem_init_heap
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
3212 DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT
, radeon_irq_emit
, DRM_AUTH
),
3213 DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT
, radeon_irq_wait
, DRM_AUTH
),
3214 DRM_IOCTL_DEF(DRM_RADEON_SETPARAM
, radeon_cp_setparam
, DRM_AUTH
),
3215 DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC
, radeon_surface_alloc
, DRM_AUTH
),
3216 DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE
, radeon_surface_free
, DRM_AUTH
)
3219 int radeon_max_ioctl
= DRM_ARRAY_SIZE(radeon_ioctls
);