3 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
4 * Use is subject to license terms.
6 /* radeon_state.c -- State support for Radeon -*- linux-c -*- */
8 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
31 * Gareth Hughes <gareth@valinux.com>
32 * Kevin E. Martin <martin@valinux.com>
35 #pragma ident "%Z%%M% %I% %E% SMI"
39 #include "drm_sarea.h"
40 #include "radeon_drm.h"
41 #include "radeon_drv.h"
42 #include "radeon_io32.h"
45 * Helper functions for client state checking and fixup
49 radeon_check_and_fixup_offset(drm_radeon_private_t
*dev_priv
,
50 drm_file_t
*filp_priv
, u32
*offset
)
53 u32 fb_end
= dev_priv
->fb_location
+ dev_priv
->fb_size
- 1;
54 struct drm_radeon_driver_file_fields
*radeon_priv
;
57 * Hrm ... the story of the offset ... So this function converts
58 * the various ideas of what userland clients might have for an
59 * offset in the card address space into an offset into the card
60 * address space :) So with a sane client, it should just keep
61 * the value intact and just do some boundary checking. However,
62 * not all clients are sane. Some older clients pass us 0 based
63 * offsets relative to the start of the framebuffer and some may
64 * assume the AGP aperture it appended to the framebuffer, so we
65 * try to detect those cases and fix them up.
67 * Note: It might be a good idea here to make sure the offset lands
68 * in some "allowed" area to protect things like the PCIE GART...
72 * First, the best case, the offset already lands in either the
73 * framebuffer or the GART mapped space
76 if (RADEON_CHECK_OFFSET(dev_priv
, off
))
80 * Ok, that didn't happen... now check if we have a zero based
81 * offset that fits in the framebuffer + gart space, apply the
82 * magic offset we get from SETPARAM or calculated from fb_location
84 if (off
< (dev_priv
->fb_size
+ dev_priv
->gart_size
)) {
85 radeon_priv
= filp_priv
->driver_priv
;
86 off
+= radeon_priv
->radeon_fb_delta
;
89 /* Finally, assume we aimed at a GART offset if beyond the fb */
91 off
= off
- fb_end
- 1 + dev_priv
->gart_vm_start
;
93 /* Now recheck and fail if out of bounds */
94 if (RADEON_CHECK_OFFSET(dev_priv
, off
)) {
95 DRM_DEBUG("offset fixed up to 0x%x\n", off
);
96 *offset
= (uint32_t)off
;
103 radeon_check_and_fixup_packets(drm_radeon_private_t
*dev_priv
,
104 drm_file_t
*filp_priv
, int id
, u32
*data
)
108 case RADEON_EMIT_PP_MISC
:
109 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
110 &data
[(RADEON_RB3D_DEPTHOFFSET
- RADEON_PP_MISC
) / 4])) {
111 DRM_ERROR("Invalid depth buffer offset\n");
116 case RADEON_EMIT_PP_CNTL
:
117 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
118 &data
[(RADEON_RB3D_COLOROFFSET
- RADEON_PP_CNTL
) / 4])) {
119 DRM_ERROR("Invalid colour buffer offset\n");
124 case R200_EMIT_PP_TXOFFSET_0
:
125 case R200_EMIT_PP_TXOFFSET_1
:
126 case R200_EMIT_PP_TXOFFSET_2
:
127 case R200_EMIT_PP_TXOFFSET_3
:
128 case R200_EMIT_PP_TXOFFSET_4
:
129 case R200_EMIT_PP_TXOFFSET_5
:
130 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
132 DRM_ERROR("Invalid R200 texture offset\n");
137 case RADEON_EMIT_PP_TXFILTER_0
:
138 case RADEON_EMIT_PP_TXFILTER_1
:
139 case RADEON_EMIT_PP_TXFILTER_2
:
140 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
141 &data
[(RADEON_PP_TXOFFSET_0
- RADEON_PP_TXFILTER_0
) / 4])) {
142 DRM_ERROR("Invalid R100 texture offset\n");
147 case R200_EMIT_PP_CUBIC_OFFSETS_0
:
148 case R200_EMIT_PP_CUBIC_OFFSETS_1
:
149 case R200_EMIT_PP_CUBIC_OFFSETS_2
:
150 case R200_EMIT_PP_CUBIC_OFFSETS_3
:
151 case R200_EMIT_PP_CUBIC_OFFSETS_4
:
152 case R200_EMIT_PP_CUBIC_OFFSETS_5
: {
154 for (i
= 0; i
< 5; i
++) {
155 if (radeon_check_and_fixup_offset(dev_priv
,
156 filp_priv
, &data
[i
])) {
157 DRM_ERROR("Invalid R200 cubic"
158 " texture offset\n");
165 case RADEON_EMIT_PP_CUBIC_OFFSETS_T0
:
166 case RADEON_EMIT_PP_CUBIC_OFFSETS_T1
:
167 case RADEON_EMIT_PP_CUBIC_OFFSETS_T2
:
170 for (i
= 0; i
< 5; i
++) {
171 if (radeon_check_and_fixup_offset(dev_priv
,
172 filp_priv
, &data
[i
])) {
173 DRM_ERROR("Invalid R100 cubic"
174 " texture offset\n");
181 case R200_EMIT_VAP_CTL
:
185 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH
, 0);
190 case RADEON_EMIT_RB3D_COLORPITCH
:
191 case RADEON_EMIT_RE_LINE_PATTERN
:
192 case RADEON_EMIT_SE_LINE_WIDTH
:
193 case RADEON_EMIT_PP_LUM_MATRIX
:
194 case RADEON_EMIT_PP_ROT_MATRIX_0
:
195 case RADEON_EMIT_RB3D_STENCILREFMASK
:
196 case RADEON_EMIT_SE_VPORT_XSCALE
:
197 case RADEON_EMIT_SE_CNTL
:
198 case RADEON_EMIT_SE_CNTL_STATUS
:
199 case RADEON_EMIT_RE_MISC
:
200 case RADEON_EMIT_PP_BORDER_COLOR_0
:
201 case RADEON_EMIT_PP_BORDER_COLOR_1
:
202 case RADEON_EMIT_PP_BORDER_COLOR_2
:
203 case RADEON_EMIT_SE_ZBIAS_FACTOR
:
204 case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT
:
205 case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED
:
206 case R200_EMIT_PP_TXCBLEND_0
:
207 case R200_EMIT_PP_TXCBLEND_1
:
208 case R200_EMIT_PP_TXCBLEND_2
:
209 case R200_EMIT_PP_TXCBLEND_3
:
210 case R200_EMIT_PP_TXCBLEND_4
:
211 case R200_EMIT_PP_TXCBLEND_5
:
212 case R200_EMIT_PP_TXCBLEND_6
:
213 case R200_EMIT_PP_TXCBLEND_7
:
214 case R200_EMIT_TCL_LIGHT_MODEL_CTL_0
:
215 case R200_EMIT_TFACTOR_0
:
216 case R200_EMIT_VTX_FMT_0
:
217 case R200_EMIT_MATRIX_SELECT_0
:
218 case R200_EMIT_TEX_PROC_CTL_2
:
219 case R200_EMIT_TCL_UCP_VERT_BLEND_CTL
:
220 case R200_EMIT_PP_TXFILTER_0
:
221 case R200_EMIT_PP_TXFILTER_1
:
222 case R200_EMIT_PP_TXFILTER_2
:
223 case R200_EMIT_PP_TXFILTER_3
:
224 case R200_EMIT_PP_TXFILTER_4
:
225 case R200_EMIT_PP_TXFILTER_5
:
226 case R200_EMIT_VTE_CNTL
:
227 case R200_EMIT_OUTPUT_VTX_COMP_SEL
:
228 case R200_EMIT_PP_TAM_DEBUG3
:
229 case R200_EMIT_PP_CNTL_X
:
230 case R200_EMIT_RB3D_DEPTHXY_OFFSET
:
231 case R200_EMIT_RE_AUX_SCISSOR_CNTL
:
232 case R200_EMIT_RE_SCISSOR_TL_0
:
233 case R200_EMIT_RE_SCISSOR_TL_1
:
234 case R200_EMIT_RE_SCISSOR_TL_2
:
235 case R200_EMIT_SE_VAP_CNTL_STATUS
:
236 case R200_EMIT_SE_VTX_STATE_CNTL
:
237 case R200_EMIT_RE_POINTSIZE
:
238 case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0
:
239 case R200_EMIT_PP_CUBIC_FACES_0
:
240 case R200_EMIT_PP_CUBIC_FACES_1
:
241 case R200_EMIT_PP_CUBIC_FACES_2
:
242 case R200_EMIT_PP_CUBIC_FACES_3
:
243 case R200_EMIT_PP_CUBIC_FACES_4
:
244 case R200_EMIT_PP_CUBIC_FACES_5
:
245 case RADEON_EMIT_PP_TEX_SIZE_0
:
246 case RADEON_EMIT_PP_TEX_SIZE_1
:
247 case RADEON_EMIT_PP_TEX_SIZE_2
:
248 case R200_EMIT_RB3D_BLENDCOLOR
:
249 case R200_EMIT_TCL_POINT_SPRITE_CNTL
:
250 case RADEON_EMIT_PP_CUBIC_FACES_0
:
251 case RADEON_EMIT_PP_CUBIC_FACES_1
:
252 case RADEON_EMIT_PP_CUBIC_FACES_2
:
253 case R200_EMIT_PP_TRI_PERF_CNTL
:
254 case R200_EMIT_PP_AFS_0
:
255 case R200_EMIT_PP_AFS_1
:
256 case R200_EMIT_ATF_TFACTOR
:
257 case R200_EMIT_PP_TXCTLALL_0
:
258 case R200_EMIT_PP_TXCTLALL_1
:
259 case R200_EMIT_PP_TXCTLALL_2
:
260 case R200_EMIT_PP_TXCTLALL_3
:
261 case R200_EMIT_PP_TXCTLALL_4
:
262 case R200_EMIT_PP_TXCTLALL_5
:
263 case R200_EMIT_VAP_PVS_CNTL
:
264 /* These packets don't contain memory offsets */
268 DRM_ERROR("Unknown state packet ID %d\n", id
);
276 radeon_check_and_fixup_packet3(drm_radeon_private_t
*dev_priv
,
277 drm_file_t
*filp_priv
, drm_radeon_kcmd_buffer_t
*cmdbuf
,
280 u32
*cmd
= (u32
*)(uintptr_t)cmdbuf
->buf
;
284 *cmdsz
= 2 + ((cmd
[0] & RADEON_CP_PACKET_COUNT_MASK
) >> 16);
286 if ((cmd
[0] & 0xc0000000) != RADEON_CP_PACKET3
) {
287 DRM_ERROR("Not a type 3 packet\n");
291 if (4 * *cmdsz
> cmdbuf
->bufsz
) {
292 DRM_ERROR("Packet size larger than size of data provided\n");
297 switch (cmd
[0] & 0xff00) {
298 /* XXX Are there old drivers needing other packets? */
300 case RADEON_3D_DRAW_IMMD
:
301 case RADEON_3D_DRAW_VBUF
:
302 case RADEON_3D_DRAW_INDX
:
303 case RADEON_WAIT_FOR_IDLE
:
305 case RADEON_3D_CLEAR_ZMASK
:
307 case RADEON_CP_NEXT_CHAR
:
308 case RADEON_CP_PLY_NEXTSCAN
:
309 case RADEON_CP_SET_SCISSORS
:
310 /* probably safe but will never need them? */
312 /* these packets are safe */
315 case RADEON_CP_3D_DRAW_IMMD_2
:
316 case RADEON_CP_3D_DRAW_VBUF_2
:
317 case RADEON_CP_3D_DRAW_INDX_2
:
318 case RADEON_3D_CLEAR_HIZ
:
319 /* safe but r200 only */
320 if (dev_priv
->microcode_version
!= UCODE_R200
) {
321 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
326 case RADEON_3D_LOAD_VBPNTR
:
327 count
= (cmd
[0] >> 16) & 0x3fff;
329 if (count
> 18) { /* 12 arrays max */
331 "Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
336 /* carefully check packet contents */
337 narrays
= cmd
[1] & ~0xc000;
340 while ((k
< narrays
) && (i
< (count
+ 2))) {
341 i
++; /* skip attribute field */
342 if (radeon_check_and_fixup_offset(dev_priv
,
343 filp_priv
, &cmd
[i
])) {
345 "Invalid offset (k=%d i=%d) ini"
346 " 3D_LOAD_VBPNTR packet.\n", k
, i
);
353 /* have one more to process, they come in pairs */
354 if (radeon_check_and_fixup_offset(dev_priv
,
355 filp_priv
, &cmd
[i
])) {
357 "Invalid offset (k=%d i=%d) in"
358 " 3D_LOAD_VBPNTR packet.\n", k
, i
);
364 /* do the counts match what we expect ? */
365 if ((k
!= narrays
) || (i
!= (count
+ 2))) {
367 "Malformed 3D_LOAD_VBPNTR packet"
368 "(k=%d i=%d narrays=%d count+1=%d).\n",
369 k
, i
, narrays
, count
+ 1);
374 case RADEON_3D_RNDR_GEN_INDX_PRIM
:
375 if (dev_priv
->microcode_version
!= UCODE_R100
) {
376 DRM_ERROR("Invalid 3d packet for r200-class chip\n");
379 if (radeon_check_and_fixup_offset(dev_priv
,
380 filp_priv
, &cmd
[1])) {
381 DRM_ERROR("Invalid rndr_gen_indx offset\n");
386 case RADEON_CP_INDX_BUFFER
:
387 if (dev_priv
->microcode_version
!= UCODE_R200
) {
388 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
391 if ((cmd
[1] & 0x8000ffff) != 0x80000810) {
393 "Invalid indx_buffer reg address %08X\n", cmd
[1]);
396 if (radeon_check_and_fixup_offset(dev_priv
,
397 filp_priv
, &cmd
[2])) {
399 "Invalid indx_buffer offset is %08X\n", cmd
[2]);
404 case RADEON_CNTL_HOSTDATA_BLT
:
405 case RADEON_CNTL_PAINT_MULTI
:
406 case RADEON_CNTL_BITBLT_MULTI
:
407 /* MSB of opcode: next DWORD GUI_CNTL */
408 if (cmd
[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
409 RADEON_GMC_DST_PITCH_OFFSET_CNTL
)) {
410 offset
= cmd
[2] << 10;
411 if (radeon_check_and_fixup_offset
412 (dev_priv
, filp_priv
, &offset
)) {
413 DRM_ERROR("Invalid first packet offset\n");
416 cmd
[2] = (cmd
[2] & 0xffc00000) | offset
>> 10;
419 if ((cmd
[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL
) &&
420 (cmd
[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL
)) {
421 offset
= cmd
[3] << 10;
422 if (radeon_check_and_fixup_offset
423 (dev_priv
, filp_priv
, &offset
)) {
424 DRM_ERROR("Invalid second packet offset\n");
427 cmd
[3] = (cmd
[3] & 0xffc00000) | offset
>> 10;
432 DRM_ERROR("Invalid packet type %x\n", cmd
[0] & 0xff00);
440 * CP hardware state programming functions
443 static inline void radeon_emit_clip_rect(drm_radeon_private_t
*dev_priv
,
444 drm_clip_rect_t
*box
)
448 DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
449 box
->x1
, box
->y1
, box
->x2
, box
->y2
);
452 OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT
, 0));
453 OUT_RING((box
->y1
<< 16) | box
->x1
);
454 OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT
, 0));
455 OUT_RING(((box
->y2
- 1) << 16) | (box
->x2
- 1));
460 static int radeon_emit_state(drm_radeon_private_t
*dev_priv
,
461 drm_file_t
*filp_priv
, drm_radeon_context_regs_t
*ctx
,
462 drm_radeon_texture_regs_t
*tex
, unsigned int dirty
)
465 DRM_DEBUG("dirty=0x%08x\n", dirty
);
467 if (dirty
& RADEON_UPLOAD_CONTEXT
) {
468 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
469 &ctx
->rb3d_depthoffset
)) {
470 DRM_ERROR("Invalid depth buffer offset\n");
474 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
475 &ctx
->rb3d_coloroffset
)) {
476 DRM_ERROR("Invalid depth buffer offset\n");
481 OUT_RING(CP_PACKET0(RADEON_PP_MISC
, 6));
482 OUT_RING(ctx
->pp_misc
);
483 OUT_RING(ctx
->pp_fog_color
);
484 OUT_RING(ctx
->re_solid_color
);
485 OUT_RING(ctx
->rb3d_blendcntl
);
486 OUT_RING(ctx
->rb3d_depthoffset
);
487 OUT_RING(ctx
->rb3d_depthpitch
);
488 OUT_RING(ctx
->rb3d_zstencilcntl
);
489 OUT_RING(CP_PACKET0(RADEON_PP_CNTL
, 2));
490 OUT_RING(ctx
->pp_cntl
);
491 OUT_RING(ctx
->rb3d_cntl
);
492 OUT_RING(ctx
->rb3d_coloroffset
);
493 OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH
, 0));
494 OUT_RING(ctx
->rb3d_colorpitch
);
498 if (dirty
& RADEON_UPLOAD_VERTFMT
) {
500 OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT
, 0));
501 OUT_RING(ctx
->se_coord_fmt
);
505 if (dirty
& RADEON_UPLOAD_LINE
) {
507 OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN
, 1));
508 OUT_RING(ctx
->re_line_pattern
);
509 OUT_RING(ctx
->re_line_state
);
510 OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH
, 0));
511 OUT_RING(ctx
->se_line_width
);
515 if (dirty
& RADEON_UPLOAD_BUMPMAP
) {
517 OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX
, 0));
518 OUT_RING(ctx
->pp_lum_matrix
);
519 OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0
, 1));
520 OUT_RING(ctx
->pp_rot_matrix_0
);
521 OUT_RING(ctx
->pp_rot_matrix_1
);
525 if (dirty
& RADEON_UPLOAD_MASKS
) {
527 OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK
, 2));
528 OUT_RING(ctx
->rb3d_stencilrefmask
);
529 OUT_RING(ctx
->rb3d_ropcntl
);
530 OUT_RING(ctx
->rb3d_planemask
);
534 if (dirty
& RADEON_UPLOAD_VIEWPORT
) {
536 OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE
, 5));
537 OUT_RING(ctx
->se_vport_xscale
);
538 OUT_RING(ctx
->se_vport_xoffset
);
539 OUT_RING(ctx
->se_vport_yscale
);
540 OUT_RING(ctx
->se_vport_yoffset
);
541 OUT_RING(ctx
->se_vport_zscale
);
542 OUT_RING(ctx
->se_vport_zoffset
);
546 if (dirty
& RADEON_UPLOAD_SETUP
) {
548 OUT_RING(CP_PACKET0(RADEON_SE_CNTL
, 0));
549 OUT_RING(ctx
->se_cntl
);
550 OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS
, 0));
551 OUT_RING(ctx
->se_cntl_status
);
555 if (dirty
& RADEON_UPLOAD_MISC
) {
557 OUT_RING(CP_PACKET0(RADEON_RE_MISC
, 0));
558 OUT_RING(ctx
->re_misc
);
562 if (dirty
& RADEON_UPLOAD_TEX0
) {
563 if (radeon_check_and_fixup_offset(dev_priv
,
564 filp_priv
, &tex
[0].pp_txoffset
)) {
565 DRM_ERROR("Invalid texture offset for unit 0\n");
570 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0
, 5));
571 OUT_RING(tex
[0].pp_txfilter
);
572 OUT_RING(tex
[0].pp_txformat
);
573 OUT_RING(tex
[0].pp_txoffset
);
574 OUT_RING(tex
[0].pp_txcblend
);
575 OUT_RING(tex
[0].pp_txablend
);
576 OUT_RING(tex
[0].pp_tfactor
);
577 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0
, 0));
578 OUT_RING(tex
[0].pp_border_color
);
582 if (dirty
& RADEON_UPLOAD_TEX1
) {
583 if (radeon_check_and_fixup_offset(dev_priv
,
584 filp_priv
, &tex
[1].pp_txoffset
)) {
585 DRM_ERROR("Invalid texture offset for unit 1\n");
590 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1
, 5));
591 OUT_RING(tex
[1].pp_txfilter
);
592 OUT_RING(tex
[1].pp_txformat
);
593 OUT_RING(tex
[1].pp_txoffset
);
594 OUT_RING(tex
[1].pp_txcblend
);
595 OUT_RING(tex
[1].pp_txablend
);
596 OUT_RING(tex
[1].pp_tfactor
);
597 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1
, 0));
598 OUT_RING(tex
[1].pp_border_color
);
602 if (dirty
& RADEON_UPLOAD_TEX2
) {
603 if (radeon_check_and_fixup_offset(dev_priv
,
604 filp_priv
, &tex
[2].pp_txoffset
)) {
605 DRM_ERROR("Invalid texture offset for unit 2\n");
610 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2
, 5));
611 OUT_RING(tex
[2].pp_txfilter
);
612 OUT_RING(tex
[2].pp_txformat
);
613 OUT_RING(tex
[2].pp_txoffset
);
614 OUT_RING(tex
[2].pp_txcblend
);
615 OUT_RING(tex
[2].pp_txablend
);
616 OUT_RING(tex
[2].pp_tfactor
);
617 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2
, 0));
618 OUT_RING(tex
[2].pp_border_color
);
626 static int radeon_emit_state2(drm_radeon_private_t
*dev_priv
,
627 drm_file_t
*filp_priv
, drm_radeon_state_t
*state
)
631 if (state
->dirty
& RADEON_UPLOAD_ZBIAS
) {
633 OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR
, 1));
634 OUT_RING(state
->context2
.se_zbias_factor
);
635 OUT_RING(state
->context2
.se_zbias_constant
);
639 return (radeon_emit_state(dev_priv
, filp_priv
,
640 &state
->context
, state
->tex
, state
->dirty
));
644 * New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
645 * 1.3 cmdbuffers allow all previous state to be updated as well as
646 * the tcl scalar and vector areas.
652 } packet
[RADEON_MAX_STATE_PACKETS
] = {
653 {RADEON_PP_MISC
, 7, "RADEON_PP_MISC"},
654 {RADEON_PP_CNTL
, 3, "RADEON_PP_CNTL"},
655 {RADEON_RB3D_COLORPITCH
, 1, "RADEON_RB3D_COLORPITCH"},
656 {RADEON_RE_LINE_PATTERN
, 2, "RADEON_RE_LINE_PATTERN"},
657 {RADEON_SE_LINE_WIDTH
, 1, "RADEON_SE_LINE_WIDTH"},
658 {RADEON_PP_LUM_MATRIX
, 1, "RADEON_PP_LUM_MATRIX"},
659 {RADEON_PP_ROT_MATRIX_0
, 2, "RADEON_PP_ROT_MATRIX_0"},
660 {RADEON_RB3D_STENCILREFMASK
, 3, "RADEON_RB3D_STENCILREFMASK"},
661 {RADEON_SE_VPORT_XSCALE
, 6, "RADEON_SE_VPORT_XSCALE"},
662 {RADEON_SE_CNTL
, 2, "RADEON_SE_CNTL"},
663 {RADEON_SE_CNTL_STATUS
, 1, "RADEON_SE_CNTL_STATUS"},
664 {RADEON_RE_MISC
, 1, "RADEON_RE_MISC"},
665 {RADEON_PP_TXFILTER_0
, 6, "RADEON_PP_TXFILTER_0"},
666 {RADEON_PP_BORDER_COLOR_0
, 1, "RADEON_PP_BORDER_COLOR_0"},
667 {RADEON_PP_TXFILTER_1
, 6, "RADEON_PP_TXFILTER_1"},
668 {RADEON_PP_BORDER_COLOR_1
, 1, "RADEON_PP_BORDER_COLOR_1"},
669 {RADEON_PP_TXFILTER_2
, 6, "RADEON_PP_TXFILTER_2"},
670 {RADEON_PP_BORDER_COLOR_2
, 1, "RADEON_PP_BORDER_COLOR_2"},
671 {RADEON_SE_ZBIAS_FACTOR
, 2, "RADEON_SE_ZBIAS_FACTOR"},
672 {RADEON_SE_TCL_OUTPUT_VTX_FMT
, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
673 {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
, 17,
674 "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
675 {R200_PP_TXCBLEND_0
, 4, "R200_PP_TXCBLEND_0"},
676 {R200_PP_TXCBLEND_1
, 4, "R200_PP_TXCBLEND_1"},
677 {R200_PP_TXCBLEND_2
, 4, "R200_PP_TXCBLEND_2"},
678 {R200_PP_TXCBLEND_3
, 4, "R200_PP_TXCBLEND_3"},
679 {R200_PP_TXCBLEND_4
, 4, "R200_PP_TXCBLEND_4"},
680 {R200_PP_TXCBLEND_5
, 4, "R200_PP_TXCBLEND_5"},
681 {R200_PP_TXCBLEND_6
, 4, "R200_PP_TXCBLEND_6"},
682 {R200_PP_TXCBLEND_7
, 4, "R200_PP_TXCBLEND_7"},
683 {R200_SE_TCL_LIGHT_MODEL_CTL_0
, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
684 {R200_PP_TFACTOR_0
, 6, "R200_PP_TFACTOR_0"},
685 {R200_SE_VTX_FMT_0
, 4, "R200_SE_VTX_FMT_0"},
686 {R200_SE_VAP_CNTL
, 1, "R200_SE_VAP_CNTL"},
687 {R200_SE_TCL_MATRIX_SEL_0
, 5, "R200_SE_TCL_MATRIX_SEL_0"},
688 {R200_SE_TCL_TEX_PROC_CTL_2
, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
689 {R200_SE_TCL_UCP_VERT_BLEND_CTL
, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
690 {R200_PP_TXFILTER_0
, 6, "R200_PP_TXFILTER_0"},
691 {R200_PP_TXFILTER_1
, 6, "R200_PP_TXFILTER_1"},
692 {R200_PP_TXFILTER_2
, 6, "R200_PP_TXFILTER_2"},
693 {R200_PP_TXFILTER_3
, 6, "R200_PP_TXFILTER_3"},
694 {R200_PP_TXFILTER_4
, 6, "R200_PP_TXFILTER_4"},
695 {R200_PP_TXFILTER_5
, 6, "R200_PP_TXFILTER_5"},
696 {R200_PP_TXOFFSET_0
, 1, "R200_PP_TXOFFSET_0"},
697 {R200_PP_TXOFFSET_1
, 1, "R200_PP_TXOFFSET_1"},
698 {R200_PP_TXOFFSET_2
, 1, "R200_PP_TXOFFSET_2"},
699 {R200_PP_TXOFFSET_3
, 1, "R200_PP_TXOFFSET_3"},
700 {R200_PP_TXOFFSET_4
, 1, "R200_PP_TXOFFSET_4"},
701 {R200_PP_TXOFFSET_5
, 1, "R200_PP_TXOFFSET_5"},
702 {R200_SE_VTE_CNTL
, 1, "R200_SE_VTE_CNTL"},
703 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL
, 1,
704 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
705 {R200_PP_TAM_DEBUG3
, 1, "R200_PP_TAM_DEBUG3"},
706 {R200_PP_CNTL_X
, 1, "R200_PP_CNTL_X"},
707 {R200_RB3D_DEPTHXY_OFFSET
, 1, "R200_RB3D_DEPTHXY_OFFSET"},
708 {R200_RE_AUX_SCISSOR_CNTL
, 1, "R200_RE_AUX_SCISSOR_CNTL"},
709 {R200_RE_SCISSOR_TL_0
, 2, "R200_RE_SCISSOR_TL_0"},
710 {R200_RE_SCISSOR_TL_1
, 2, "R200_RE_SCISSOR_TL_1"},
711 {R200_RE_SCISSOR_TL_2
, 2, "R200_RE_SCISSOR_TL_2"},
712 {R200_SE_VAP_CNTL_STATUS
, 1, "R200_SE_VAP_CNTL_STATUS"},
713 {R200_SE_VTX_STATE_CNTL
, 1, "R200_SE_VTX_STATE_CNTL"},
714 {R200_RE_POINTSIZE
, 1, "R200_RE_POINTSIZE"},
715 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0
, 4,
716 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
717 {R200_PP_CUBIC_FACES_0
, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
718 {R200_PP_CUBIC_OFFSET_F1_0
, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
719 {R200_PP_CUBIC_FACES_1
, 1, "R200_PP_CUBIC_FACES_1"},
720 {R200_PP_CUBIC_OFFSET_F1_1
, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
721 {R200_PP_CUBIC_FACES_2
, 1, "R200_PP_CUBIC_FACES_2"},
722 {R200_PP_CUBIC_OFFSET_F1_2
, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
723 {R200_PP_CUBIC_FACES_3
, 1, "R200_PP_CUBIC_FACES_3"},
724 {R200_PP_CUBIC_OFFSET_F1_3
, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
725 {R200_PP_CUBIC_FACES_4
, 1, "R200_PP_CUBIC_FACES_4"},
726 {R200_PP_CUBIC_OFFSET_F1_4
, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
727 {R200_PP_CUBIC_FACES_5
, 1, "R200_PP_CUBIC_FACES_5"},
728 {R200_PP_CUBIC_OFFSET_F1_5
, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
729 {RADEON_PP_TEX_SIZE_0
, 2, "RADEON_PP_TEX_SIZE_0"},
730 {RADEON_PP_TEX_SIZE_1
, 2, "RADEON_PP_TEX_SIZE_1"},
731 {RADEON_PP_TEX_SIZE_2
, 2, "RADEON_PP_TEX_SIZE_2"},
732 {R200_RB3D_BLENDCOLOR
, 3, "R200_RB3D_BLENDCOLOR"},
733 {R200_SE_TCL_POINT_SPRITE_CNTL
, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
734 {RADEON_PP_CUBIC_FACES_0
, 1, "RADEON_PP_CUBIC_FACES_0"},
735 {RADEON_PP_CUBIC_OFFSET_T0_0
, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
736 {RADEON_PP_CUBIC_FACES_1
, 1, "RADEON_PP_CUBIC_FACES_1"},
737 {RADEON_PP_CUBIC_OFFSET_T1_0
, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
738 {RADEON_PP_CUBIC_FACES_2
, 1, "RADEON_PP_CUBIC_FACES_2"},
739 {RADEON_PP_CUBIC_OFFSET_T2_0
, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
740 {R200_PP_TRI_PERF
, 2, "R200_PP_TRI_PERF"},
741 {R200_PP_AFS_0
, 32, "R200_PP_AFS_0"}, /* 85 */
742 {R200_PP_AFS_1
, 32, "R200_PP_AFS_1"},
743 {R200_PP_TFACTOR_0
, 8, "R200_ATF_TFACTOR"},
744 {R200_PP_TXFILTER_0
, 8, "R200_PP_TXCTLALL_0"},
745 {R200_PP_TXFILTER_1
, 8, "R200_PP_TXCTLALL_1"},
746 {R200_PP_TXFILTER_2
, 8, "R200_PP_TXCTLALL_2"},
747 {R200_PP_TXFILTER_3
, 8, "R200_PP_TXCTLALL_3"},
748 {R200_PP_TXFILTER_4
, 8, "R200_PP_TXCTLALL_4"},
749 {R200_PP_TXFILTER_5
, 8, "R200_PP_TXCTLALL_5"},
750 {R200_VAP_PVS_CNTL_1
, 2, "R200_VAP_PVS_CNTL"},
754 * Performance monitoring functions
757 static void radeon_clear_box(drm_radeon_private_t
*dev_priv
,
758 int x
, int y
, int w
, int h
, int r
, int g
, int b
)
763 x
+= dev_priv
->sarea_priv
->boxes
[0].x1
;
764 y
+= dev_priv
->sarea_priv
->boxes
[0].y1
;
766 switch (dev_priv
->color_fmt
) {
767 case RADEON_COLOR_FORMAT_RGB565
:
768 color
= (((r
& 0xf8) << 8) |
769 ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3));
771 case RADEON_COLOR_FORMAT_ARGB8888
:
773 color
= (((0xfful
) << 24) | (r
<< 16) | (g
<< 8) | b
);
778 RADEON_WAIT_UNTIL_3D_IDLE();
779 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK
, 0));
780 OUT_RING(0xffffffff);
785 OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI
, 4));
786 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
787 RADEON_GMC_BRUSH_SOLID_COLOR
|
788 (dev_priv
->color_fmt
<< 8) |
789 RADEON_GMC_SRC_DATATYPE_COLOR
|
790 RADEON_ROP3_P
| RADEON_GMC_CLR_CMP_CNTL_DIS
);
792 if (dev_priv
->page_flipping
&& dev_priv
->current_page
== 1) {
793 OUT_RING(dev_priv
->front_pitch_offset
);
795 OUT_RING(dev_priv
->back_pitch_offset
);
800 OUT_RING((x
<< 16) | y
);
801 OUT_RING((w
<< 16) | h
);
806 static void radeon_cp_performance_boxes(drm_radeon_private_t
*dev_priv
)
809 * Collapse various things into a wait flag -- trying to
810 * guess if userspase slept -- better just to have them tell us.
812 if (dev_priv
->stats
.last_frame_reads
> 1 ||
813 dev_priv
->stats
.last_clear_reads
> dev_priv
->stats
.clears
) {
814 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
817 if (dev_priv
->stats
.freelist_loops
) {
818 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
821 /* Purple box for page flipping */
822 if (dev_priv
->stats
.boxes
& RADEON_BOX_FLIP
)
823 radeon_clear_box(dev_priv
, 4, 4, 8, 8, 255, 0, 255);
825 /* Red box if we have to wait for idle at any point */
826 if (dev_priv
->stats
.boxes
& RADEON_BOX_WAIT_IDLE
)
827 radeon_clear_box(dev_priv
, 16, 4, 8, 8, 255, 0, 0);
829 /* Blue box: lost context? */
831 /* Yellow box for texture swaps */
832 if (dev_priv
->stats
.boxes
& RADEON_BOX_TEXTURE_LOAD
)
833 radeon_clear_box(dev_priv
, 40, 4, 8, 8, 255, 255, 0);
835 /* Green box if hardware never idles (as far as we can tell) */
836 if (!(dev_priv
->stats
.boxes
& RADEON_BOX_DMA_IDLE
))
837 radeon_clear_box(dev_priv
, 64, 4, 8, 8, 0, 255, 0);
840 * Draw bars indicating number of buffers allocated
841 * (not a great measure, easily confused)
843 if (dev_priv
->stats
.requested_bufs
) {
844 if (dev_priv
->stats
.requested_bufs
> 100)
845 dev_priv
->stats
.requested_bufs
= 100;
847 radeon_clear_box(dev_priv
, 4, 16,
848 dev_priv
->stats
.requested_bufs
, 4, 196, 128, 128);
851 (void) memset(&dev_priv
->stats
, 0, sizeof (dev_priv
->stats
));
856 * CP command dispatch functions
859 static void radeon_cp_dispatch_clear(drm_device_t
*dev
,
860 drm_radeon_clear_t
*clear
, drm_radeon_clear_rect_t
*depth_boxes
)
862 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
863 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
864 drm_radeon_depth_clear_t
*depth_clear
= &dev_priv
->depth_clear
;
865 int nbox
= sarea_priv
->nbox
;
866 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
867 unsigned int flags
= clear
->flags
;
868 u32 rb3d_cntl
= 0, rb3d_stencilrefmask
= 0;
871 DRM_DEBUG("flags = 0x%x\n", flags
);
873 dev_priv
->stats
.clears
++;
875 if (dev_priv
->page_flipping
&& dev_priv
->current_page
== 1) {
876 unsigned int tmp
= flags
;
878 flags
&= ~(RADEON_FRONT
| RADEON_BACK
);
879 if (tmp
& RADEON_FRONT
)
880 flags
|= RADEON_BACK
;
881 if (tmp
& RADEON_BACK
)
882 flags
|= RADEON_FRONT
;
885 if (flags
& (RADEON_FRONT
| RADEON_BACK
)) {
890 * Ensure the 3D stream is idle before doing a
891 * 2D fill to clear the front or back buffer.
893 RADEON_WAIT_UNTIL_3D_IDLE();
895 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK
, 0));
896 OUT_RING(clear
->color_mask
);
900 /* Make sure we restore the 3D state next time. */
901 dev_priv
->sarea_priv
->ctx_owner
= 0;
903 for (i
= 0; i
< nbox
; i
++) {
906 int w
= pbox
[i
].x2
- x
;
907 int h
= pbox
[i
].y2
- y
;
909 DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
912 if (flags
& RADEON_FRONT
) {
916 (RADEON_CNTL_PAINT_MULTI
, 4));
917 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
918 RADEON_GMC_BRUSH_SOLID_COLOR
|
919 (dev_priv
-> color_fmt
<< 8) |
920 RADEON_GMC_SRC_DATATYPE_COLOR
|
922 RADEON_GMC_CLR_CMP_CNTL_DIS
);
924 OUT_RING(dev_priv
->front_pitch_offset
);
925 OUT_RING(clear
->clear_color
);
927 OUT_RING((x
<< 16) | y
);
928 OUT_RING((w
<< 16) | h
);
933 if (flags
& RADEON_BACK
) {
937 (RADEON_CNTL_PAINT_MULTI
, 4));
938 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
939 RADEON_GMC_BRUSH_SOLID_COLOR
|
940 (dev_priv
-> color_fmt
<< 8) |
941 RADEON_GMC_SRC_DATATYPE_COLOR
|
943 RADEON_GMC_CLR_CMP_CNTL_DIS
);
945 OUT_RING(dev_priv
->back_pitch_offset
);
946 OUT_RING(clear
->clear_color
);
948 OUT_RING((x
<< 16) | y
);
949 OUT_RING((w
<< 16) | h
);
958 * no docs available, based on reverse engeneering
959 * by Stephane Marchesin
961 if ((flags
& (RADEON_DEPTH
| RADEON_STENCIL
)) &&
962 (flags
& RADEON_CLEAR_FASTZ
)) {
965 int depthpixperline
=
966 dev_priv
->depth_fmt
==
967 RADEON_DEPTH_FORMAT_16BIT_INT_Z
?
968 (dev_priv
->depth_pitch
/ 2) :
969 (dev_priv
-> depth_pitch
/ 4);
973 u32 tempRB3D_DEPTHCLEARVALUE
= clear
->clear_depth
|
974 ((clear
->depth_mask
& 0xff) << 24);
977 * Make sure we restore the 3D state next time.
978 * we haven't touched any "normal" state - still
981 dev_priv
->sarea_priv
->ctx_owner
= 0;
983 if ((dev_priv
->flags
& RADEON_HAS_HIERZ
) &&
984 (flags
& RADEON_USE_HIERZ
)) {
985 /* FIXME : reverse engineer that for Rx00 cards */
987 * FIXME : the mask supposedly contains low-res
988 * z values. So can't set just to the max (0xff?
989 * or actually 0x3fff?), need to take z clear
990 * value into account?
993 * pattern seems to work for r100, though get
994 * slight rendering errors with glxgears. If
995 * hierz is not enabled for r100, only 4 bits
996 * which indicate clear (15,16,31,32, all zero)
997 * matter, the other ones are ignored, and the
998 * same clear mask can be used. That's very
999 * different behaviour than R200 which needs
1000 * different clear mask and different number
1001 * of tiles to clear if hierz is enabled or not !?!
1003 clearmask
= (0xff << 22) | (0xff << 6) | 0x003f003f;
1006 * clear mask : chooses the clearing pattern.
1007 * rv250: could be used to clear only parts of macrotiles
1008 * (but that would get really complicated...)?
1009 * bit 0 and 1 (either or both of them ?!?!) are used to
1010 * not clear tile (or maybe one of the bits indicates if
1011 * the tile is compressed or not), bit 2 and 3 to not
1012 * clear tile 1,...,.
1013 * Pattern is as follows:
1014 * | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
1015 * bits -------------------------------------------------
1016 * | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
1017 * rv100: clearmask covers 2x8 4x1 tiles, but one clear
1018 * still covers 256 pixels ?!?
1024 RADEON_WAIT_UNTIL_2D_IDLE();
1025 OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE
,
1026 tempRB3D_DEPTHCLEARVALUE
);
1027 /* what offset is this exactly ? */
1028 OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET
, 0);
1029 /* need ctlstat, otherwise get some strange black flickering */
1030 OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT
,
1031 RADEON_RB3D_ZC_FLUSH_ALL
);
1034 for (i
= 0; i
< nbox
; i
++) {
1035 int tileoffset
, nrtilesx
, nrtilesy
, j
;
1037 * it looks like r200 needs rv-style clears, at
1038 * least if hierz is not enabled?
1040 if ((dev_priv
->flags
& RADEON_HAS_HIERZ
) &&
1041 !(dev_priv
->microcode_version
== UCODE_R200
)) {
1043 * FIXME : figure this out for r200 (when hierz
1044 * is enabled). Or maybe r200 actually doesn't
1045 * need to put the low-res z value into the tile
1046 * cache like r100, but just needs to clear the
1047 * hi-level z-buffer? Works for R100, both with
1048 * hierz and without.R100 seems to operate on
1049 * 2x1 8x8 tiles, but... odd: offset/nrtiles
1050 * need to be 64 pix (4 blocka) aligned?
1051 * Potentially problematic with resolutions
1052 * which are not 64 pix aligned?
1055 ((pbox
[i
].y1
>> 3) * depthpixperline
+
1058 ((pbox
[i
].x2
& ~63) -
1059 (pbox
[i
].x1
& ~63)) >> 4;
1061 (pbox
[i
].y2
>> 3) - (pbox
[i
].y1
>> 3);
1062 for (j
= 0; j
<= nrtilesy
; j
++) {
1065 (RADEON_3D_CLEAR_ZMASK
, 2));
1067 OUT_RING(tileoffset
* 8);
1068 /* the number of tiles to clear */
1069 OUT_RING(nrtilesx
+ 4);
1072 * chooses the clearing pattern.
1074 OUT_RING(clearmask
);
1076 tileoffset
+= depthpixperline
>> 6;
1078 } else if (dev_priv
->microcode_version
== UCODE_R200
) {
1079 /* works for rv250. */
1081 * find first macro tile
1082 * (8x2 4x4 z-pixels on rv250)
1085 ((pbox
[i
].y1
>> 3) * depthpixperline
+
1088 (pbox
[i
].x2
>> 5) - (pbox
[i
].x1
>> 5);
1090 (pbox
[i
].y2
>> 3) - (pbox
[i
].y1
>> 3);
1091 for (j
= 0; j
<= nrtilesy
; j
++) {
1094 (RADEON_3D_CLEAR_ZMASK
, 2));
1097 * judging by the first tile
1098 * offset needed, could possibly
1099 * directly address/clear 4x4
1100 * tiles instead of 8x2 * 4x4
1101 * macro tiles, though would
1102 * still need clear mask for
1103 * right/bottom if truely 4x4
1104 * granularity is desired ?
1106 OUT_RING(tileoffset
* 16);
1107 /* the number of tiles to clear */
1108 OUT_RING(nrtilesx
+ 1);
1111 * chooses the clearing pattern.
1113 OUT_RING(clearmask
);
1115 tileoffset
+= depthpixperline
>> 5;
1117 } else { /* rv 100 */
1118 /* rv100 might not need 64 pix alignment */
1119 /* offsets are, hmm, weird */
1121 ((pbox
[i
].y1
>> 4) * depthpixperline
+
1124 ((pbox
[i
].x2
& ~63) -
1125 (pbox
[i
].x1
& ~63)) >> 4;
1127 (pbox
[i
].y2
>> 4) - (pbox
[i
].y1
>> 4);
1128 for (j
= 0; j
<= nrtilesy
; j
++) {
1131 (RADEON_3D_CLEAR_ZMASK
, 2));
1132 OUT_RING(tileoffset
* 128);
1133 /* the number of tiles to clear */
1134 OUT_RING(nrtilesx
+ 4);
1137 * chooses the clearing pattern.
1139 OUT_RING(clearmask
);
1141 tileoffset
+= depthpixperline
>> 6;
1146 /* TODO don't always clear all hi-level z tiles */
1147 if ((dev_priv
->flags
& RADEON_HAS_HIERZ
) &&
1148 (dev_priv
->microcode_version
== UCODE_R200
) &&
1149 (flags
& RADEON_USE_HIERZ
))
1151 * r100 and cards without hierarchical z-buffer
1152 * have no high-level z-buffer
1155 * FIXME : the mask supposedly contains low-res
1156 * z values. So can't set just to the max (0xff?
1157 * or actually 0x3fff?), need to take z clear value
1162 OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ
, 2));
1163 OUT_RING(0x0); /* First tile */
1165 OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
1171 * We have to clear the depth and/or stencil buffers by
1172 * rendering a quad into just those buffers. Thus, we have to
1173 * make sure the 3D engine is configured correctly.
1175 else if ((dev_priv
->microcode_version
== UCODE_R200
) &&
1176 (flags
& (RADEON_DEPTH
| RADEON_STENCIL
))) {
1181 int tempRB3D_ZSTENCILCNTL
;
1182 int tempRB3D_STENCILREFMASK
;
1183 int tempRB3D_PLANEMASK
;
1185 int tempSE_VTE_CNTL
;
1186 int tempSE_VTX_FMT_0
;
1187 int tempSE_VTX_FMT_1
;
1188 int tempSE_VAP_CNTL
;
1189 int tempRE_AUX_SCISSOR_CNTL
;
1194 tempRB3D_CNTL
= depth_clear
->rb3d_cntl
;
1196 tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
1197 tempRB3D_STENCILREFMASK
= 0x0;
1199 tempSE_CNTL
= depth_clear
->se_cntl
;
1204 (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
1205 (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT
));
1207 tempRB3D_PLANEMASK
= 0x0;
1209 tempRE_AUX_SCISSOR_CNTL
= 0x0;
1212 SE_VTE_CNTL__VTX_XY_FMT_MASK
| SE_VTE_CNTL__VTX_Z_FMT_MASK
;
1214 /* Vertex format (X, Y, Z, W) */
1216 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK
|
1217 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK
;
1218 tempSE_VTX_FMT_1
= 0x0;
1221 * Depth buffer specific enables
1223 if (flags
& RADEON_DEPTH
) {
1224 /* Enable depth buffer */
1225 tempRB3D_CNTL
|= RADEON_Z_ENABLE
;
1227 /* Disable depth buffer */
1228 tempRB3D_CNTL
&= ~RADEON_Z_ENABLE
;
1232 * Stencil buffer specific enables
1234 if (flags
& RADEON_STENCIL
) {
1235 tempRB3D_CNTL
|= RADEON_STENCIL_ENABLE
;
1236 tempRB3D_STENCILREFMASK
= clear
->depth_mask
;
1238 tempRB3D_CNTL
&= ~RADEON_STENCIL_ENABLE
;
1239 tempRB3D_STENCILREFMASK
= 0x00000000;
1242 if (flags
& RADEON_USE_COMP_ZBUF
) {
1243 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_COMPRESSION_ENABLE
|
1244 RADEON_Z_DECOMPRESSION_ENABLE
;
1246 if (flags
& RADEON_USE_HIERZ
) {
1247 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_HIERARCHY_ENABLE
;
1251 RADEON_WAIT_UNTIL_2D_IDLE();
1253 OUT_RING_REG(RADEON_PP_CNTL
, tempPP_CNTL
);
1254 OUT_RING_REG(R200_RE_CNTL
, tempRE_CNTL
);
1255 OUT_RING_REG(RADEON_RB3D_CNTL
, tempRB3D_CNTL
);
1256 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL
, tempRB3D_ZSTENCILCNTL
);
1257 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK
,
1258 tempRB3D_STENCILREFMASK
);
1259 OUT_RING_REG(RADEON_RB3D_PLANEMASK
, tempRB3D_PLANEMASK
);
1260 OUT_RING_REG(RADEON_SE_CNTL
, tempSE_CNTL
);
1261 OUT_RING_REG(R200_SE_VTE_CNTL
, tempSE_VTE_CNTL
);
1262 OUT_RING_REG(R200_SE_VTX_FMT_0
, tempSE_VTX_FMT_0
);
1263 OUT_RING_REG(R200_SE_VTX_FMT_1
, tempSE_VTX_FMT_1
);
1264 OUT_RING_REG(R200_SE_VAP_CNTL
, tempSE_VAP_CNTL
);
1265 OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL
, tempRE_AUX_SCISSOR_CNTL
);
1268 /* Make sure we restore the 3D state next time. */
1269 dev_priv
->sarea_priv
->ctx_owner
= 0;
1271 for (i
= 0; i
< nbox
; i
++) {
1274 * Funny that this should be required --
1277 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1280 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2
, 12));
1281 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST
|
1282 RADEON_PRIM_WALK_RING
|
1283 (3 << RADEON_NUM_VERTICES_SHIFT
)));
1284 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1285 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y1
]);
1286 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1287 OUT_RING(0x3f800000);
1288 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1289 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1290 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1291 OUT_RING(0x3f800000);
1292 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X2
]);
1293 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1294 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1295 OUT_RING(0x3f800000);
1298 } else if ((flags
& (RADEON_DEPTH
| RADEON_STENCIL
))) {
1300 int tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
1302 rb3d_cntl
= depth_clear
->rb3d_cntl
;
1304 if (flags
& RADEON_DEPTH
) {
1305 rb3d_cntl
|= RADEON_Z_ENABLE
;
1307 rb3d_cntl
&= ~RADEON_Z_ENABLE
;
1310 if (flags
& RADEON_STENCIL
) {
1311 rb3d_cntl
|= RADEON_STENCIL_ENABLE
;
1313 /* misnamed field */
1314 rb3d_stencilrefmask
= clear
->depth_mask
;
1317 rb3d_cntl
&= ~RADEON_STENCIL_ENABLE
;
1318 rb3d_stencilrefmask
= 0x00000000;
1321 if (flags
& RADEON_USE_COMP_ZBUF
) {
1322 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_COMPRESSION_ENABLE
|
1323 RADEON_Z_DECOMPRESSION_ENABLE
;
1325 if (flags
& RADEON_USE_HIERZ
) {
1326 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_HIERARCHY_ENABLE
;
1330 RADEON_WAIT_UNTIL_2D_IDLE();
1332 OUT_RING(CP_PACKET0(RADEON_PP_CNTL
, 1));
1333 OUT_RING(0x00000000);
1334 OUT_RING(rb3d_cntl
);
1336 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL
, tempRB3D_ZSTENCILCNTL
);
1337 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK
, rb3d_stencilrefmask
);
1338 OUT_RING_REG(RADEON_RB3D_PLANEMASK
, 0x00000000);
1339 OUT_RING_REG(RADEON_SE_CNTL
, depth_clear
->se_cntl
);
1342 /* Make sure we restore the 3D state next time. */
1343 dev_priv
->sarea_priv
->ctx_owner
= 0;
1345 for (i
= 0; i
< nbox
; i
++) {
1348 * Funny that this should be required --
1351 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1355 OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD
, 13));
1356 OUT_RING(RADEON_VTX_Z_PRESENT
|
1357 RADEON_VTX_PKCOLOR_PRESENT
);
1358 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST
|
1359 RADEON_PRIM_WALK_RING
|
1360 RADEON_MAOS_ENABLE
|
1361 RADEON_VTX_FMT_RADEON_MODE
|
1362 (3 << RADEON_NUM_VERTICES_SHIFT
)));
1364 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1365 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y1
]);
1366 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1369 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1370 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1371 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1374 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X2
]);
1375 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1376 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1384 * Increment the clear counter. The client-side 3D driver must
1385 * wait on this value before performing the clear ioctl. We
1386 * need this because the card's so damned fast...
1388 dev_priv
->sarea_priv
->last_clear
++;
1392 RADEON_CLEAR_AGE(dev_priv
->sarea_priv
->last_clear
);
1393 RADEON_WAIT_UNTIL_IDLE();
1398 static void radeon_cp_dispatch_swap(drm_device_t
*dev
)
1400 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1401 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1402 int nbox
= sarea_priv
->nbox
;
1403 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
1407 /* Do some trivial performance monitoring... */
1408 if (dev_priv
->do_boxes
)
1409 radeon_cp_performance_boxes(dev_priv
);
1412 * Wait for the 3D stream to idle before dispatching the bitblt.
1413 * This will prevent data corruption between the two streams.
1417 RADEON_WAIT_UNTIL_3D_IDLE();
1421 for (i
= 0; i
< nbox
; i
++) {
1424 int w
= pbox
[i
].x2
- x
;
1425 int h
= pbox
[i
].y2
- y
;
1427 DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x
, y
, w
, h
);
1431 OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL
, 0));
1432 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
1433 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1434 RADEON_GMC_BRUSH_NONE
|
1435 (dev_priv
->color_fmt
<< 8) |
1436 RADEON_GMC_SRC_DATATYPE_COLOR
|
1438 RADEON_DP_SRC_SOURCE_MEMORY
|
1439 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
1441 /* Make this work even if front & back are flipped: */
1442 OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET
, 1));
1443 if (dev_priv
->current_page
== 0) {
1444 OUT_RING(dev_priv
->back_pitch_offset
);
1445 OUT_RING(dev_priv
->front_pitch_offset
);
1447 OUT_RING(dev_priv
->front_pitch_offset
);
1448 OUT_RING(dev_priv
->back_pitch_offset
);
1451 OUT_RING(CP_PACKET0(RADEON_SRC_X_Y
, 2));
1452 OUT_RING((x
<< 16) | y
);
1453 OUT_RING((x
<< 16) | y
);
1454 OUT_RING((w
<< 16) | h
);
1460 * Increment the frame counter. The client-side 3D driver must
1461 * throttle the framerate by waiting for this value before
1462 * performing the swapbuffer ioctl.
1464 dev_priv
->sarea_priv
->last_frame
++;
1468 RADEON_FRAME_AGE(dev_priv
->sarea_priv
->last_frame
);
1469 RADEON_WAIT_UNTIL_2D_IDLE();
1474 static void radeon_cp_dispatch_flip(drm_device_t
*dev
)
1476 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1477 drm_sarea_t
*sarea
= (drm_sarea_t
*)dev_priv
->sarea
->handle
;
1478 int offset
= (dev_priv
->current_page
== 1)
1479 ? dev_priv
->front_offset
: dev_priv
->back_offset
;
1481 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
1483 dev_priv
->current_page
, dev_priv
->sarea_priv
->pfCurrentPage
);
1485 /* Do some trivial performance monitoring... */
1486 if (dev_priv
->do_boxes
) {
1487 dev_priv
->stats
.boxes
|= RADEON_BOX_FLIP
;
1488 radeon_cp_performance_boxes(dev_priv
);
1491 /* Update the frame offsets for both CRTCs */
1494 RADEON_WAIT_UNTIL_3D_IDLE();
1495 OUT_RING_REG(RADEON_CRTC_OFFSET
,
1496 ((sarea
->frame
.y
* dev_priv
->front_pitch
+
1497 sarea
->frame
.x
* (dev_priv
->color_fmt
- 2)) & ~7) + offset
);
1498 OUT_RING_REG(RADEON_CRTC2_OFFSET
,
1499 dev_priv
->sarea_priv
->crtc2_base
+ offset
);
1504 * Increment the frame counter. The client-side 3D driver must
1505 * throttle the framerate by waiting for this value before
1506 * performing the swapbuffer ioctl.
1508 dev_priv
->sarea_priv
->last_frame
++;
1509 dev_priv
->sarea_priv
->pfCurrentPage
= dev_priv
->current_page
=
1510 1 - dev_priv
->current_page
;
1514 RADEON_FRAME_AGE(dev_priv
->sarea_priv
->last_frame
);
1519 static int bad_prim_vertex_nr(int primitive
, int nr
)
1521 switch (primitive
& RADEON_PRIM_TYPE_MASK
) {
1522 case RADEON_PRIM_TYPE_NONE
:
1523 case RADEON_PRIM_TYPE_POINT
:
1525 case RADEON_PRIM_TYPE_LINE
:
1526 return ((nr
& 1) || nr
== 0);
1527 case RADEON_PRIM_TYPE_LINE_STRIP
:
1529 case RADEON_PRIM_TYPE_TRI_LIST
:
1530 case RADEON_PRIM_TYPE_3VRT_POINT_LIST
:
1531 case RADEON_PRIM_TYPE_3VRT_LINE_LIST
:
1532 case RADEON_PRIM_TYPE_RECT_LIST
:
1533 return (nr
% 3 || nr
== 0);
1534 case RADEON_PRIM_TYPE_TRI_FAN
:
1535 case RADEON_PRIM_TYPE_TRI_STRIP
:
1544 unsigned int finish
;
1546 unsigned int numverts
;
1547 unsigned int offset
;
1548 unsigned int vc_format
;
1549 } drm_radeon_tcl_prim_t
;
1551 static void radeon_cp_dispatch_vertex(drm_device_t
*dev
,
1552 drm_buf_t
*buf
, drm_radeon_tcl_prim_t
*prim
)
1554 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1555 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1556 int offset
= dev_priv
->gart_buffers_offset
+ buf
->offset
+ prim
->start
;
1557 int numverts
= (int)prim
->numverts
;
1558 int nbox
= sarea_priv
->nbox
;
1562 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1563 prim
->prim
, prim
->vc_format
, prim
->start
,
1564 prim
->finish
, prim
->numverts
);
1566 if (bad_prim_vertex_nr(prim
->prim
, prim
->numverts
)) {
1567 DRM_ERROR("bad prim %x numverts %d\n",
1568 prim
->prim
, prim
->numverts
);
1573 /* Emit the next cliprect */
1575 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1578 /* Emit the vertex buffer rendering commands */
1581 OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM
, 3));
1584 OUT_RING(prim
->vc_format
);
1585 OUT_RING(prim
->prim
| RADEON_PRIM_WALK_LIST
|
1586 RADEON_COLOR_ORDER_RGBA
|
1587 RADEON_VTX_FMT_RADEON_MODE
|
1588 (numverts
<< RADEON_NUM_VERTICES_SHIFT
));
1596 static void radeon_cp_discard_buffer(drm_device_t
*dev
, drm_buf_t
*buf
)
1598 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1599 drm_radeon_buf_priv_t
*buf_priv
= buf
->dev_private
;
1602 buf_priv
->age
= ++dev_priv
->sarea_priv
->last_dispatch
;
1604 /* Emit the vertex buffer age */
1606 RADEON_DISPATCH_AGE(buf_priv
->age
);
1613 static void radeon_cp_dispatch_indirect(drm_device_t
*dev
,
1614 drm_buf_t
*buf
, int start
, int end
)
1616 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1618 DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf
->idx
, start
, end
);
1621 int offset
= (dev_priv
->gart_buffers_offset
+
1622 buf
->offset
+ start
);
1623 int dwords
= (end
- start
+ 3) / sizeof (u32
);
1626 * Indirect buffer data must be an even number of
1627 * dwords, so if we've been given an odd number we must
1628 * pad the data with a Type-2 CP packet.
1631 u32
*data
= (u32
*)(uintptr_t)
1632 ((char *)dev
->agp_buffer_map
->handle
1633 + buf
->offset
+ start
);
1634 data
[dwords
++] = RADEON_CP_PACKET2
;
1637 /* Fire off the indirect buffer */
1640 OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE
, 1));
1648 static void radeon_cp_dispatch_indices(drm_device_t
*dev
,
1649 drm_buf_t
*elt_buf
, drm_radeon_tcl_prim_t
*prim
)
1651 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1652 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1653 int offset
= dev_priv
->gart_buffers_offset
+ prim
->offset
;
1657 int start
= prim
->start
+ RADEON_INDEX_PRIM_OFFSET
;
1658 int count
= (prim
->finish
- start
) / sizeof (u16
);
1659 int nbox
= sarea_priv
->nbox
;
1661 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1662 prim
->prim
, prim
->vc_format
, prim
->start
,
1663 prim
->finish
, prim
->offset
, prim
->numverts
);
1665 if (bad_prim_vertex_nr(prim
->prim
, count
)) {
1666 DRM_ERROR("bad prim %x count %d\n", prim
->prim
, count
);
1670 if (start
>= prim
->finish
|| (prim
->start
& 0x7)) {
1671 DRM_ERROR("buffer prim %d\n", prim
->prim
);
1675 dwords
= (prim
->finish
- prim
->start
+ 3) / sizeof (u32
);
1677 data
= (u32
*)(uintptr_t)((char *)dev
->agp_buffer_map
->handle
+
1678 elt_buf
->offset
+ prim
->start
);
1680 data
[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM
, dwords
- 2);
1682 data
[2] = prim
->numverts
;
1683 data
[3] = prim
->vc_format
;
1684 data
[4] = (prim
->prim
|
1685 RADEON_PRIM_WALK_IND
|
1686 RADEON_COLOR_ORDER_RGBA
|
1687 RADEON_VTX_FMT_RADEON_MODE
|
1688 (count
<< RADEON_NUM_VERTICES_SHIFT
));
1692 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1694 radeon_cp_dispatch_indirect(dev
, elt_buf
,
1695 prim
->start
, prim
->finish
);
1702 #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1705 static int radeon_cp_dispatch_texture(drm_file_t
*fpriv
,
1706 drm_device_t
*dev
, drm_radeon_texture_t
*tex
,
1707 drm_radeon_tex_image_t
*image
, int mode
)
1709 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1713 const u8 __user
*data
;
1714 int size
, dwords
, tex_width
, blit_width
, spitch
;
1717 u32 texpitch
, microtile
;
1722 if (radeon_check_and_fixup_offset(dev_priv
, fpriv
, &tex
->offset
)) {
1723 DRM_ERROR("Invalid destination offset\n");
1727 dev_priv
->stats
.boxes
|= RADEON_BOX_TEXTURE_LOAD
;
1730 * Flush the pixel cache. This ensures no pixel data gets mixed
1731 * up with the texture data from the host data blit, otherwise
1732 * part of the texture image may be corrupted.
1735 RADEON_FLUSH_CACHE();
1736 RADEON_WAIT_UNTIL_IDLE();
1740 * The compiler won't optimize away a division by a variable,
1741 * even if the only legal values are powers of two. Thus, we'll
1742 * use a shift instead.
1744 switch (tex
->format
) {
1745 case RADEON_TXFORMAT_ARGB8888
:
1746 case RADEON_TXFORMAT_RGBA8888
:
1747 format
= RADEON_COLOR_FORMAT_ARGB8888
;
1748 tex_width
= tex
->width
* 4;
1749 blit_width
= image
->width
* 4;
1751 case RADEON_TXFORMAT_AI88
:
1752 case RADEON_TXFORMAT_ARGB1555
:
1753 case RADEON_TXFORMAT_RGB565
:
1754 case RADEON_TXFORMAT_ARGB4444
:
1755 case RADEON_TXFORMAT_VYUY422
:
1756 case RADEON_TXFORMAT_YVYU422
:
1757 format
= RADEON_COLOR_FORMAT_RGB565
;
1758 tex_width
= tex
->width
* 2;
1759 blit_width
= image
->width
* 2;
1761 case RADEON_TXFORMAT_I8
:
1762 case RADEON_TXFORMAT_RGB332
:
1763 format
= RADEON_COLOR_FORMAT_CI8
;
1764 tex_width
= tex
->width
* 1;
1765 blit_width
= image
->width
* 1;
1768 DRM_ERROR("invalid texture format %d\n", tex
->format
);
1771 spitch
= blit_width
>> 6;
1772 if (spitch
== 0 && image
->height
> 1)
1775 texpitch
= tex
->pitch
;
1776 if ((texpitch
<< 22) & RADEON_DST_TILE_MICRO
) {
1778 if (tex_width
< 64) {
1779 texpitch
&= ~(RADEON_DST_TILE_MICRO
>> 22);
1780 /* we got tiled coordinates, untile them */
1786 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width
, tex
->height
, blit_width
);
1789 DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1790 tex
->offset
>> 10, tex
->pitch
, tex
->format
,
1791 image
->x
, image
->y
, image
->width
, image
->height
);
1794 * Make a copy of some parameters in case we have to
1795 * update them for a multi-pass texture blit.
1797 height
= image
->height
;
1798 data
= (const u8 __user
*)image
->data
;
1800 size
= height
* blit_width
;
1802 if (size
> RADEON_MAX_TEXTURE_SIZE
) {
1803 height
= RADEON_MAX_TEXTURE_SIZE
/ blit_width
;
1804 size
= height
* blit_width
;
1805 } else if (size
< 4 && size
> 0) {
1807 } else if (size
== 0) {
1811 buf
= radeon_freelist_get(dev
);
1814 radeon_do_cp_idle(dev_priv
);
1815 buf
= radeon_freelist_get(dev
);
1819 DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
1821 #ifdef _MULTI_DATAMODEL
1822 if (ddi_model_convert_from(mode
& FMODELS
) ==
1824 drm_radeon_tex_image_32_t image32
;
1825 image32
.x
= image
->x
;
1826 image32
.y
= image
->y
;
1827 image32
.width
= image
->width
;
1828 image32
.height
= image
->height
;
1829 image32
.data
= (uint32_t)(uintptr_t)image
->data
;
1830 DRM_COPYTO_WITH_RETURN(tex
->image
, &image32
,
1834 DRM_COPYTO_WITH_RETURN(tex
->image
, image
,
1836 #ifdef _MULTI_DATAMODEL
1843 * Dispatch the indirect buffer.
1845 buffer
= (u32
*)(uintptr_t)
1846 ((char *)dev
->agp_buffer_map
->handle
+ buf
->offset
);
1850 #define RADEON_COPY_MT(_buf, _data, _width) \
1852 if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1853 DRM_ERROR("%d: EFAULT on pad, %d bytes\n", \
1854 __LINE__, (_width)); \
1861 * texture micro tiling in use, minimum texture
1862 * width is thus 16 bytes. however, we cannot use
1863 * blitter directly for texture width < 64 bytes,
1864 * since minimum tex pitch is 64 bytes and we need
1865 * this to match the texture width, otherwise the
1866 * blitter will tile it wrong. Thus, tiling manually
1867 * in this case. Additionally, need to special case
1868 * tex height = 1, since our actual image will have
1869 * height 2 and we need to ensure we don't read
1870 * beyond the texture size from user space.
1872 if (tex
->height
== 1) {
1873 if (tex_width
>= 64 || tex_width
<= 16) {
1874 RADEON_COPY_MT(buffer
, data
,
1875 (int)(tex_width
* sizeof (u32
)));
1876 } else if (tex_width
== 32) {
1877 RADEON_COPY_MT(buffer
, data
, 16);
1878 RADEON_COPY_MT(buffer
+ 8,
1881 } else if (tex_width
>= 64 || tex_width
== 16) {
1882 RADEON_COPY_MT(buffer
, data
,
1883 (int)(dwords
* sizeof (u32
)));
1884 } else if (tex_width
< 16) {
1885 for (i
= 0; i
< tex
->height
; i
++) {
1886 RADEON_COPY_MT(buffer
, data
, tex_width
);
1890 } else if (tex_width
== 32) {
1892 * TODO: make sure this works when not
1893 * fitting in one buffer
1894 * (i.e. 32bytes x 2048...)
1896 for (i
= 0; i
< tex
->height
; i
+= 2) {
1897 RADEON_COPY_MT(buffer
, data
, 16);
1899 RADEON_COPY_MT(buffer
+ 8, data
, 16);
1901 RADEON_COPY_MT(buffer
+ 4, data
, 16);
1903 RADEON_COPY_MT(buffer
+ 12, data
, 16);
1909 if (tex_width
>= 32) {
1911 * Texture image width is larger than the
1912 * minimum, so we can upload it directly.
1914 RADEON_COPY_MT(buffer
, data
,
1915 (int)(dwords
* sizeof (u32
)));
1918 * Texture image width is less than the minimum,
1919 * so we need to pad out each image scanline to
1920 * the minimum width.
1922 for (i
= 0; i
< tex
->height
; i
++) {
1923 RADEON_COPY_MT(buffer
, data
, tex_width
);
1930 #undef RADEON_COPY_MT
1933 offset
= dev_priv
->gart_buffers_offset
+ buf
->offset
;
1936 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI
, 5));
1937 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
1938 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1939 RADEON_GMC_BRUSH_NONE
|
1941 RADEON_GMC_SRC_DATATYPE_COLOR
|
1943 RADEON_DP_SRC_SOURCE_MEMORY
|
1944 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
1945 OUT_RING((spitch
<< 22) | (offset
>> 10));
1946 OUT_RING((texpitch
<< 22) | (tex
->offset
>> 10));
1948 OUT_RING((image
->x
<< 16) | image
->y
);
1949 OUT_RING((image
->width
<< 16) | height
);
1950 RADEON_WAIT_UNTIL_2D_IDLE();
1955 radeon_cp_discard_buffer(dev
, buf
);
1957 /* Update the input parameters for next time */
1959 image
->height
-= height
;
1960 image
->data
= (const u8 __user
*)image
->data
+ size
;
1961 } while (image
->height
> 0);
1964 * Flush the pixel cache after the blit completes. This ensures
1965 * the texture data is written out to memory before rendering
1969 RADEON_FLUSH_CACHE();
1970 RADEON_WAIT_UNTIL_2D_IDLE();
1976 static void radeon_cp_dispatch_stipple(drm_device_t
*dev
, u32
*stipple
)
1978 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1985 OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR
, 0));
1986 OUT_RING(0x00000000);
1988 OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA
, 31));
1989 for (i
= 0; i
< 32; i
++) {
1990 OUT_RING(stipple
[i
]);
1996 static void radeon_apply_surface_regs(int surf_index
,
1997 drm_radeon_private_t
*dev_priv
)
1999 if (!dev_priv
->mmio
)
2002 (void) radeon_do_cp_idle(dev_priv
);
2004 RADEON_WRITE(RADEON_SURFACE0_INFO
+ 16 * surf_index
,
2005 dev_priv
->surfaces
[surf_index
].flags
);
2006 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND
+ 16 * surf_index
,
2007 dev_priv
->surfaces
[surf_index
].lower
);
2008 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND
+ 16 * surf_index
,
2009 dev_priv
->surfaces
[surf_index
].upper
);
2013 * Allocates a virtual surface
2014 * doesn't always allocate a real surface, will stretch an existing
2015 * surface when possible.
2017 * Note that refcount can be at most 2, since during a free refcount=3
2018 * might mean we have to allocate a new surface which might not always
2020 * For example : we allocate three contigous surfaces ABC. If B is
2021 * freed, we suddenly need two surfaces to store A and C, which might
2022 * not always be available.
2024 static int alloc_surface(drm_radeon_surface_alloc_t
*new,
2025 drm_radeon_private_t
*dev_priv
, drm_file_t
*filp
)
2027 struct radeon_virt_surface
*s
;
2029 int virt_surface_index
;
2030 uint32_t new_upper
, new_lower
;
2032 new_lower
= new->address
;
2033 new_upper
= new_lower
+ new->size
- 1;
2036 if ((new_lower
>= new_upper
) || (new->flags
== 0) || (new->size
== 0) ||
2037 ((new_upper
& RADEON_SURF_ADDRESS_FIXED_MASK
) !=
2038 RADEON_SURF_ADDRESS_FIXED_MASK
) ||
2039 ((new_lower
& RADEON_SURF_ADDRESS_FIXED_MASK
) != 0))
2042 /* make sure there is no overlap with existing surfaces */
2043 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
2044 if ((dev_priv
->surfaces
[i
].refcount
!= 0) &&
2045 (((new_lower
>= dev_priv
->surfaces
[i
].lower
) &&
2046 (new_lower
< dev_priv
->surfaces
[i
].upper
)) ||
2047 ((new_lower
< dev_priv
->surfaces
[i
].lower
) &&
2048 (new_upper
> dev_priv
->surfaces
[i
].lower
)))) {
2053 /* find a virtual surface */
2054 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++)
2055 if (dev_priv
->virt_surfaces
[i
].filp
== 0)
2057 if (i
== 2 * RADEON_MAX_SURFACES
) {
2060 virt_surface_index
= i
;
2062 /* try to reuse an existing surface */
2063 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
2065 if ((dev_priv
->surfaces
[i
].refcount
== 1) &&
2066 (new->flags
== dev_priv
->surfaces
[i
].flags
) &&
2067 (new_upper
+ 1 == dev_priv
->surfaces
[i
].lower
)) {
2068 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
2069 s
->surface_index
= i
;
2070 s
->lower
= new_lower
;
2071 s
->upper
= new_upper
;
2072 s
->flags
= new->flags
;
2074 dev_priv
->surfaces
[i
].refcount
++;
2075 dev_priv
->surfaces
[i
].lower
= s
->lower
;
2076 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
2077 return (virt_surface_index
);
2081 if ((dev_priv
->surfaces
[i
].refcount
== 1) &&
2082 (new->flags
== dev_priv
->surfaces
[i
].flags
) &&
2083 (new_lower
== dev_priv
->surfaces
[i
].upper
+ 1)) {
2084 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
2085 s
->surface_index
= i
;
2086 s
->lower
= new_lower
;
2087 s
->upper
= new_upper
;
2088 s
->flags
= new->flags
;
2090 dev_priv
->surfaces
[i
].refcount
++;
2091 dev_priv
->surfaces
[i
].upper
= s
->upper
;
2092 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
2093 return (virt_surface_index
);
2097 /* okay, we need a new one */
2098 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
2099 if (dev_priv
->surfaces
[i
].refcount
== 0) {
2100 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
2101 s
->surface_index
= i
;
2102 s
->lower
= new_lower
;
2103 s
->upper
= new_upper
;
2104 s
->flags
= new->flags
;
2106 dev_priv
->surfaces
[i
].refcount
= 1;
2107 dev_priv
->surfaces
[i
].lower
= s
->lower
;
2108 dev_priv
->surfaces
[i
].upper
= s
->upper
;
2109 dev_priv
->surfaces
[i
].flags
= s
->flags
;
2110 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
2111 return (virt_surface_index
);
2115 /* we didn't find anything */
2120 free_surface(drm_file_t
*filp
, drm_radeon_private_t
*dev_priv
, int lower
)
2122 struct radeon_virt_surface
*s
;
2125 /* find the virtual surface */
2126 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++) {
2127 s
= &(dev_priv
->virt_surfaces
[i
]);
2129 if ((lower
== s
->lower
) && (filp
== s
->filp
)) {
2130 if (dev_priv
->surfaces
[s
->surface_index
].
2132 dev_priv
->surfaces
[s
->surface_index
].
2135 if (dev_priv
->surfaces
[s
->surface_index
].
2137 dev_priv
->surfaces
[s
->surface_index
].
2140 dev_priv
->surfaces
[s
->surface_index
].refcount
--;
2141 if (dev_priv
->surfaces
[s
->surface_index
].
2143 dev_priv
->surfaces
[s
->surface_index
].
2146 radeon_apply_surface_regs(s
->surface_index
,
2156 static void radeon_surfaces_release(drm_file_t
*filp
,
2157 drm_radeon_private_t
*dev_priv
)
2161 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++) {
2162 if (dev_priv
->virt_surfaces
[i
].filp
== filp
)
2163 (void) free_surface(filp
, dev_priv
,
2164 dev_priv
->virt_surfaces
[i
].lower
);
2172 static int radeon_surface_alloc(DRM_IOCTL_ARGS
)
2175 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2176 drm_radeon_surface_alloc_t alloc
;
2179 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2183 DRM_COPYFROM_WITH_RETURN(&alloc
, (void *)data
, sizeof (alloc
));
2185 if (alloc_surface(&alloc
, dev_priv
, fpriv
) == -1)
2192 static int radeon_surface_free(DRM_IOCTL_ARGS
)
2195 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2196 drm_radeon_surface_free_t memfree
;
2199 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2203 DRM_COPYFROM_WITH_RETURN(&memfree
, (void *)data
, sizeof (memfree
));
2204 if (free_surface(fpriv
, dev_priv
, memfree
.address
)) {
2212 static int radeon_cp_clear(DRM_IOCTL_ARGS
)
2215 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2216 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2217 drm_radeon_clear_t clear
;
2218 drm_radeon_clear_rect_t depth_boxes
[RADEON_NR_SAREA_CLIPRECTS
];
2220 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2222 #ifdef _MULTI_DATAMODEL
2223 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
2224 drm_radeon_clear_32_t clear32
;
2225 DRM_COPYFROM_WITH_RETURN(&clear32
, (void *)data
,
2227 clear
.flags
= clear32
.flags
;
2228 clear
.clear_color
= clear32
.clear_color
;
2229 clear
.clear_depth
= clear32
.clear_depth
;
2230 clear
.color_mask
= clear32
.color_mask
;
2231 clear
.depth_mask
= clear32
.depth_mask
;
2232 clear
.depth_boxes
= (void*)(uintptr_t)clear32
.depth_boxes
;
2235 DRM_COPYFROM_WITH_RETURN(&clear
, (void *)data
, sizeof (clear
));
2236 #ifdef _MULTI_DATAMODEL
2240 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2242 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2243 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
2245 if (DRM_COPY_FROM_USER(&depth_boxes
, clear
.depth_boxes
,
2246 sarea_priv
->nbox
* sizeof (depth_boxes
[0])))
2249 radeon_cp_dispatch_clear(dev
, &clear
, depth_boxes
);
2256 * Not sure why this isn't set all the time:
2258 static int radeon_do_init_pageflip(drm_device_t
*dev
)
2260 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2264 RADEON_WAIT_UNTIL_3D_IDLE();
2265 OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL
, 0));
2266 OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL
) |
2267 RADEON_CRTC_OFFSET_FLIP_CNTL
);
2268 OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL
, 0));
2269 OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL
) |
2270 RADEON_CRTC_OFFSET_FLIP_CNTL
);
2273 dev_priv
->page_flipping
= 1;
2274 dev_priv
->current_page
= 0;
2275 dev_priv
->sarea_priv
->pfCurrentPage
= dev_priv
->current_page
;
2281 * Called whenever a client dies, from drm_release.
2282 * NOTE: Lock isn't necessarily held when this is called!
2284 static int radeon_do_cleanup_pageflip(drm_device_t
*dev
)
2286 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2288 if (dev_priv
->current_page
!= 0)
2289 radeon_cp_dispatch_flip(dev
);
2291 dev_priv
->page_flipping
= 0;
2296 * Swapping and flipping are different operations, need different ioctls.
2297 * They can & should be intermixed to support multiple 3d windows.
2300 static int radeon_cp_flip(DRM_IOCTL_ARGS
)
2303 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2305 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2307 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2309 if (!dev_priv
->page_flipping
)
2310 (void) radeon_do_init_pageflip(dev
);
2312 radeon_cp_dispatch_flip(dev
);
2319 static int radeon_cp_swap(DRM_IOCTL_ARGS
)
2322 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2323 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2325 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2327 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2329 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2330 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
2332 radeon_cp_dispatch_swap(dev
);
2333 dev_priv
->sarea_priv
->ctx_owner
= 0;
2340 static int radeon_cp_vertex(DRM_IOCTL_ARGS
)
2343 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2344 drm_radeon_sarea_t
*sarea_priv
;
2345 drm_device_dma_t
*dma
= dev
->dma
;
2347 drm_radeon_vertex_t vertex
;
2348 drm_radeon_tcl_prim_t prim
;
2350 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2353 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2357 sarea_priv
= dev_priv
->sarea_priv
;
2359 DRM_COPYFROM_WITH_RETURN(&vertex
, (void *)data
, sizeof (vertex
));
2361 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2362 DRM_CURRENTPID
, vertex
.idx
, vertex
.count
, vertex
.discard
);
2364 if (vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
2365 DRM_ERROR("buffer index %d (of %d max)\n",
2366 vertex
.idx
, dma
->buf_count
- 1);
2369 if (vertex
.prim
< 0 || vertex
.prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
2370 DRM_ERROR("buffer prim %d\n", vertex
.prim
);
2374 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2375 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2377 buf
= dma
->buflist
[vertex
.idx
];
2379 if (buf
->filp
!= fpriv
) {
2380 DRM_ERROR("process %d using buffer owned by %p\n",
2381 DRM_CURRENTPID
, buf
->filp
);
2385 DRM_ERROR("sending pending buffer %d\n", vertex
.idx
);
2390 * Build up a prim_t record:
2393 buf
->used
= vertex
.count
; /* not used? */
2395 if (sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
2396 if (radeon_emit_state(dev_priv
, fpriv
,
2397 &sarea_priv
->context_state
,
2398 sarea_priv
->tex_state
,
2399 sarea_priv
->dirty
)) {
2400 DRM_ERROR("radeon_emit_state failed\n");
2404 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
2405 RADEON_UPLOAD_TEX1IMAGES
|
2406 RADEON_UPLOAD_TEX2IMAGES
|
2407 RADEON_REQUIRE_QUIESCENCE
);
2411 prim
.finish
= vertex
.count
; /* unused */
2412 prim
.prim
= vertex
.prim
;
2413 prim
.numverts
= vertex
.count
;
2414 prim
.vc_format
= dev_priv
->sarea_priv
->vc_format
;
2416 radeon_cp_dispatch_vertex(dev
, buf
, &prim
);
2419 if (vertex
.discard
) {
2420 radeon_cp_discard_buffer(dev
, buf
);
2428 static int radeon_cp_indices(DRM_IOCTL_ARGS
)
2431 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2432 drm_radeon_sarea_t
*sarea_priv
;
2433 drm_device_dma_t
*dma
= dev
->dma
;
2435 drm_radeon_indices_t elts
;
2436 drm_radeon_tcl_prim_t prim
;
2439 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2442 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2445 sarea_priv
= dev_priv
->sarea_priv
;
2447 DRM_COPYFROM_WITH_RETURN(&elts
, (void *)data
, sizeof (elts
));
2449 DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2450 DRM_CURRENTPID
, elts
.idx
, elts
.start
, elts
.end
, elts
.discard
);
2452 if (elts
.idx
< 0 || elts
.idx
>= dma
->buf_count
) {
2453 DRM_ERROR("buffer index %d (of %d max)\n",
2454 elts
.idx
, dma
->buf_count
- 1);
2457 if (elts
.prim
< 0 || elts
.prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
2458 DRM_ERROR("buffer prim %d\n", elts
.prim
);
2462 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2463 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2465 buf
= dma
->buflist
[elts
.idx
];
2467 if (buf
->filp
!= fpriv
) {
2468 DRM_ERROR("process %d using buffer owned by %p\n",
2469 DRM_CURRENTPID
, buf
->filp
);
2473 DRM_ERROR("sending pending buffer %d\n", elts
.idx
);
2477 /* count = (elts.end - elts.start) / sizeof(u16); */
2478 elts
.start
-= RADEON_INDEX_PRIM_OFFSET
;
2480 if (elts
.start
& 0x7) {
2481 DRM_ERROR("misaligned buffer 0x%x\n", elts
.start
);
2484 if (elts
.start
< buf
->used
) {
2485 DRM_ERROR("no header 0x%x - 0x%x\n", elts
.start
, buf
->used
);
2489 buf
->used
= elts
.end
;
2491 if (sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
2492 if (radeon_emit_state(dev_priv
, fpriv
,
2493 &sarea_priv
->context_state
,
2494 sarea_priv
->tex_state
,
2495 sarea_priv
->dirty
)) {
2496 DRM_ERROR("radeon_emit_state failed\n");
2500 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
2501 RADEON_UPLOAD_TEX1IMAGES
|
2502 RADEON_UPLOAD_TEX2IMAGES
|
2503 RADEON_REQUIRE_QUIESCENCE
);
2507 * Build up a prim_t record:
2509 prim
.start
= elts
.start
;
2510 prim
.finish
= elts
.end
;
2511 prim
.prim
= elts
.prim
;
2512 prim
.offset
= 0; /* offset from start of dma buffers */
2513 prim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
2514 prim
.vc_format
= dev_priv
->sarea_priv
->vc_format
;
2516 radeon_cp_dispatch_indices(dev
, buf
, &prim
);
2518 radeon_cp_discard_buffer(dev
, buf
);
2526 static int radeon_cp_texture(DRM_IOCTL_ARGS
)
2529 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2530 drm_radeon_texture_t tex
;
2531 drm_radeon_tex_image_t image
;
2534 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2536 #ifdef _MULTI_DATAMODEL
2537 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
2538 drm_radeon_texture_32_t tex32
;
2539 drm_radeon_tex_image_32_t image32
;
2541 DRM_COPYFROM_WITH_RETURN(&tex32
, (void *)data
, sizeof (tex32
));
2542 if (tex32
.image
== 0) {
2543 DRM_ERROR("null texture image!\n");
2546 if (DRM_COPY_FROM_USER(&image32
,
2547 (void *)(uintptr_t)tex32
.image
, sizeof (image32
))) {
2548 cmn_err(CE_WARN
, "copyin32 failed");
2552 tex
.offset
= tex32
.offset
;
2553 tex
.pitch
= tex32
.pitch
;
2554 tex
.format
= tex32
.format
;
2555 tex
.width
= tex32
.width
;
2556 tex
.height
= tex32
.height
;
2557 tex
.image
= (void*)(uintptr_t)tex32
.image
;
2559 image
.x
= image32
.x
;
2560 image
.y
= image32
.y
;
2561 image
.width
= image32
.width
;
2562 image
.height
= image32
.height
;
2563 image
.data
= (void*)(uintptr_t)image32
.data
;
2567 DRM_COPYFROM_WITH_RETURN(&tex
, (void *)data
, sizeof (tex
));
2568 if (tex
.image
== NULL
) {
2571 if (DRM_COPY_FROM_USER(&image
,
2572 (drm_radeon_tex_image_t
*)tex
.image
, sizeof (image
))) {
2575 #ifdef _MULTI_DATAMODEL
2579 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2580 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2582 ret
= radeon_cp_dispatch_texture(fpriv
, dev
, &tex
, &image
, mode
);
2589 static int radeon_cp_stipple(DRM_IOCTL_ARGS
)
2592 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2593 drm_radeon_stipple_t stipple
;
2596 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2598 #ifdef _MULTI_DATAMODEL
2599 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
2600 drm_radeon_stipple_32_t stipple32
;
2601 DRM_COPYFROM_WITH_RETURN(&stipple32
, (void *)data
,
2602 sizeof (stipple32
));
2603 stipple
.mask
= (void *)(uintptr_t)stipple32
.mask
;
2606 DRM_COPYFROM_WITH_RETURN(&stipple
, (void *)data
,
2608 #ifdef _MULTI_DATAMODEL
2611 if (DRM_COPY_FROM_USER(&mask
, stipple
.mask
, 32 * sizeof (u32
)))
2615 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2617 radeon_cp_dispatch_stipple(dev
, mask
);
2624 static int radeon_cp_indirect(DRM_IOCTL_ARGS
)
2627 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2628 drm_device_dma_t
*dma
= dev
->dma
;
2630 drm_radeon_indirect_t indirect
;
2633 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2636 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2640 DRM_COPYFROM_WITH_RETURN(&indirect
, (void *) data
, sizeof (indirect
));
2642 DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
2643 indirect
.idx
, indirect
.start
, indirect
.end
, indirect
.discard
);
2645 if (indirect
.idx
< 0 || indirect
.idx
>= dma
->buf_count
) {
2646 DRM_ERROR("buffer index %d (of %d max)\n",
2647 indirect
.idx
, dma
->buf_count
- 1);
2651 buf
= dma
->buflist
[indirect
.idx
];
2653 if (buf
->filp
!= fpriv
) {
2654 DRM_ERROR("process %d using buffer owned by %p\n",
2655 DRM_CURRENTPID
, buf
->filp
);
2659 DRM_ERROR("sending pending buffer %d\n", indirect
.idx
);
2663 if (indirect
.start
< buf
->used
) {
2664 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2665 indirect
.start
, buf
->used
);
2669 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2670 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2672 buf
->used
= indirect
.end
;
2675 * Wait for the 3D stream to idle before the indirect buffer
2676 * containing 2D acceleration commands is processed.
2680 RADEON_WAIT_UNTIL_3D_IDLE();
2685 * Dispatch the indirect buffer full of commands from the
2686 * X server. This is insecure and is thus only available to
2687 * privileged clients.
2689 radeon_cp_dispatch_indirect(dev
, buf
, indirect
.start
, indirect
.end
);
2690 if (indirect
.discard
) {
2691 radeon_cp_discard_buffer(dev
, buf
);
2699 static int radeon_cp_vertex2(DRM_IOCTL_ARGS
)
2702 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2703 drm_radeon_sarea_t
*sarea_priv
;
2704 drm_device_dma_t
*dma
= dev
->dma
;
2706 drm_radeon_vertex2_t vertex
;
2708 unsigned char laststate
;
2710 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
2713 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2717 sarea_priv
= dev_priv
->sarea_priv
;
2720 #ifdef _MULTI_DATAMODEL
2721 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
2722 drm_radeon_vertex2_32_t vertex32
;
2724 DRM_COPYFROM_WITH_RETURN(&vertex32
, (void *) data
,
2726 vertex
.idx
= vertex32
.idx
;
2727 vertex
.discard
= vertex32
.discard
;
2728 vertex
.nr_states
= vertex32
.nr_states
;
2729 vertex
.state
= (void *) (uintptr_t)vertex32
.state
;
2730 vertex
.nr_prims
= vertex32
.nr_prims
;
2731 vertex
.prim
= (void *)(uintptr_t)vertex32
.prim
;
2734 DRM_COPYFROM_WITH_RETURN(&vertex
, (void *) data
,
2736 #ifdef _MULTI_DATAMODEL
2740 DRM_DEBUG("pid=%d index=%d discard=%d\n",
2741 DRM_CURRENTPID
, vertex
.idx
, vertex
.discard
);
2743 if (vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
2744 DRM_ERROR("buffer index %d (of %d max)\n",
2745 vertex
.idx
, dma
->buf_count
- 1);
2749 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2750 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2752 buf
= dma
->buflist
[vertex
.idx
];
2754 if (buf
->filp
!= fpriv
) {
2755 DRM_ERROR("process %d using buffer owned by %p\n",
2756 DRM_CURRENTPID
, buf
->filp
);
2761 DRM_ERROR("sending pending buffer %d\n", vertex
.idx
);
2765 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2768 for (laststate
= 0xff, i
= 0; i
< vertex
.nr_prims
; i
++) {
2769 drm_radeon_prim_t prim
;
2770 drm_radeon_tcl_prim_t tclprim
;
2772 if (DRM_COPY_FROM_USER(&prim
, &vertex
.prim
[i
], sizeof (prim
)))
2775 if (prim
.stateidx
!= laststate
) {
2776 drm_radeon_state_t state
;
2778 if (DRM_COPY_FROM_USER(&state
,
2779 &vertex
.state
[prim
.stateidx
], sizeof (state
)))
2782 if (radeon_emit_state2(dev_priv
, fpriv
, &state
)) {
2783 DRM_ERROR("radeon_emit_state2 failed\n");
2787 laststate
= prim
.stateidx
;
2790 tclprim
.start
= prim
.start
;
2791 tclprim
.finish
= prim
.finish
;
2792 tclprim
.prim
= prim
.prim
;
2793 tclprim
.vc_format
= prim
.vc_format
;
2795 if (prim
.prim
& RADEON_PRIM_WALK_IND
) {
2796 tclprim
.offset
= prim
.numverts
* 64;
2797 tclprim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
2799 radeon_cp_dispatch_indices(dev
, buf
, &tclprim
);
2801 tclprim
.numverts
= prim
.numverts
;
2802 tclprim
.offset
= 0; /* not used */
2804 radeon_cp_dispatch_vertex(dev
, buf
, &tclprim
);
2807 if (sarea_priv
->nbox
== 1)
2808 sarea_priv
->nbox
= 0;
2811 if (vertex
.discard
) {
2812 radeon_cp_discard_buffer(dev
, buf
);
2819 static int radeon_emit_packets(drm_radeon_private_t
*dev_priv
,
2820 drm_file_t
*filp_priv
, drm_radeon_cmd_header_t header
,
2821 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2823 int id
= (int)header
.packet
.packet_id
;
2825 u32
*data
= (u32
*)(uintptr_t)cmdbuf
->buf
;
2828 if (id
>= RADEON_MAX_STATE_PACKETS
)
2831 sz
= packet
[id
].len
;
2832 reg
= packet
[id
].start
;
2834 if (sz
* sizeof (int) > cmdbuf
->bufsz
) {
2835 DRM_ERROR("Packet size provided larger than data provided\n");
2839 if (radeon_check_and_fixup_packets(dev_priv
, filp_priv
, id
, data
)) {
2840 DRM_ERROR("Packet verification failed\n");
2845 OUT_RING(CP_PACKET0(reg
, (sz
- 1)));
2846 OUT_RING_TABLE(data
, sz
);
2849 cmdbuf
->buf
+= sz
* sizeof (int);
2850 cmdbuf
->bufsz
-= sz
* sizeof (int);
2855 radeon_emit_scalars(drm_radeon_private_t
*dev_priv
,
2856 drm_radeon_cmd_header_t header
, drm_radeon_kcmd_buffer_t
*cmdbuf
)
2858 int sz
= header
.scalars
.count
;
2859 int start
= header
.scalars
.offset
;
2860 int stride
= header
.scalars
.stride
;
2864 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG
, 0));
2865 OUT_RING(start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
2866 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG
, sz
- 1));
2867 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2869 cmdbuf
->buf
+= sz
* sizeof (int);
2870 cmdbuf
->bufsz
-= sz
* sizeof (int);
2878 radeon_emit_scalars2(drm_radeon_private_t
*dev_priv
,
2879 drm_radeon_cmd_header_t header
, drm_radeon_kcmd_buffer_t
*cmdbuf
)
2881 int sz
= header
.scalars
.count
;
2882 int start
= ((unsigned int)header
.scalars
.offset
) + 0x100;
2883 int stride
= header
.scalars
.stride
;
2887 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG
, 0));
2888 OUT_RING(start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
2889 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG
, sz
- 1));
2890 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2892 cmdbuf
->buf
+= sz
* sizeof (int);
2893 cmdbuf
->bufsz
-= sz
* sizeof (int);
2898 radeon_emit_vectors(drm_radeon_private_t
*dev_priv
,
2899 drm_radeon_cmd_header_t header
, drm_radeon_kcmd_buffer_t
*cmdbuf
)
2901 int sz
= header
.vectors
.count
;
2902 int start
= header
.vectors
.offset
;
2903 int stride
= header
.vectors
.stride
;
2907 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH
, 0);
2908 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG
, 0));
2909 OUT_RING(start
| (stride
<< RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT
));
2910 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG
, (sz
- 1)));
2911 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2914 cmdbuf
->buf
+= sz
* sizeof (int);
2915 cmdbuf
->bufsz
-= sz
* sizeof (int);
2920 radeon_emit_veclinear(drm_radeon_private_t
*dev_priv
,
2921 drm_radeon_cmd_header_t header
, drm_radeon_kcmd_buffer_t
*cmdbuf
)
2923 int sz
= header
.veclinear
.count
* 4;
2924 int start
= header
.veclinear
.addr_lo
| (header
.veclinear
.addr_hi
<< 8);
2929 if (sz
* 4 > cmdbuf
->bufsz
)
2933 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH
, 0);
2934 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG
, 0));
2935 OUT_RING(start
| (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT
));
2936 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG
, (sz
- 1)));
2937 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2940 cmdbuf
->buf
+= sz
* sizeof (int);
2941 cmdbuf
->bufsz
-= sz
* sizeof (int);
2946 radeon_emit_packet3(drm_device_t
*dev
, drm_file_t
*filp_priv
,
2947 drm_radeon_kcmd_buffer_t
*cmdbuf
)
2949 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2955 if ((ret
= radeon_check_and_fixup_packet3(dev_priv
,
2956 filp_priv
, cmdbuf
, &cmdsz
))) {
2957 DRM_ERROR("Packet verification failed\n");
2962 OUT_RING_TABLE(cmdbuf
->buf
, cmdsz
);
2965 cmdbuf
->buf
+= cmdsz
* 4;
2966 cmdbuf
->bufsz
-= cmdsz
* 4;
2970 static int radeon_emit_packet3_cliprect(drm_device_t
*dev
,
2971 drm_file_t
*filp_priv
,
2972 drm_radeon_kcmd_buffer_t
*cmdbuf
,
2975 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2976 drm_clip_rect_t box
;
2979 drm_clip_rect_t __user
*boxes
= cmdbuf
->boxes
;
2983 if ((ret
= radeon_check_and_fixup_packet3(dev_priv
,
2984 filp_priv
, cmdbuf
, &cmdsz
))) {
2985 DRM_ERROR("Packet verification failed\n");
2993 if (i
< cmdbuf
->nbox
) {
2994 if (DRM_COPY_FROM_USER(&box
, &boxes
[i
], sizeof (box
)))
2997 * FIXME The second and subsequent times round
2998 * this loop, send a WAIT_UNTIL_3D_IDLE before
2999 * calling emit_clip_rect(). This fixes a
3000 * lockup on fast machines when sending
3001 * several cliprects with a cmdbuf, as when
3002 * waving a 2D window over a 3D
3003 * window. Something in the commands from user
3004 * space seems to hang the card when they're
3005 * sent several times in a row. That would be
3006 * the correct place to fix it but this works
3007 * around it until I can figure that out - Tim
3012 RADEON_WAIT_UNTIL_3D_IDLE();
3015 radeon_emit_clip_rect(dev_priv
, &box
);
3019 OUT_RING_TABLE(cmdbuf
->buf
, cmdsz
);
3022 } while (++i
< cmdbuf
->nbox
);
3023 if (cmdbuf
->nbox
== 1)
3027 cmdbuf
->buf
+= cmdsz
* 4;
3028 cmdbuf
->bufsz
-= cmdsz
* 4;
3033 radeon_emit_wait(drm_device_t
*dev
, int flags
)
3035 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3038 DRM_DEBUG("%s: %x\n", __FUNCTION__
, flags
);
3040 case RADEON_WAIT_2D
:
3042 RADEON_WAIT_UNTIL_2D_IDLE();
3045 case RADEON_WAIT_3D
:
3047 RADEON_WAIT_UNTIL_3D_IDLE();
3050 case RADEON_WAIT_2D
| RADEON_WAIT_3D
:
3052 RADEON_WAIT_UNTIL_IDLE();
3063 static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS
)
3066 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3067 drm_device_dma_t
*dma
= dev
->dma
;
3068 drm_buf_t
*buf
= NULL
;
3070 drm_radeon_kcmd_buffer_t cmdbuf
;
3071 drm_radeon_cmd_header_t header
;
3072 int orig_nbox
, orig_bufsz
;
3075 LOCK_TEST_WITH_RETURN(dev
, fpriv
);
3078 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
3082 #ifdef _MULTI_DATAMODEL
3083 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
3084 drm_radeon_kcmd_buffer_32_t cmdbuf32
;
3086 DRM_COPYFROM_WITH_RETURN(&cmdbuf32
, (void *)data
,
3088 cmdbuf
.bufsz
= cmdbuf32
.bufsz
;
3089 cmdbuf
.buf
= (void *)(uintptr_t)cmdbuf32
.buf
;
3090 cmdbuf
.nbox
= cmdbuf32
.nbox
;
3091 cmdbuf
.boxes
= (void *)(uintptr_t)cmdbuf32
.boxes
;
3094 DRM_COPYFROM_WITH_RETURN(&cmdbuf
, (void *) data
,
3096 #ifdef _MULTI_DATAMODEL
3099 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
3100 VB_AGE_TEST_WITH_RETURN(dev_priv
);
3102 if (cmdbuf
.bufsz
> 64 * 1024 || cmdbuf
.bufsz
< 0) {
3107 * Allocate an in-kernel area and copy in the cmdbuf. Do this
3108 * to avoid races between checking values and using those values
3109 * in other code, and simply to avoid a lot of function calls
3112 orig_bufsz
= cmdbuf
.bufsz
;
3113 if (orig_bufsz
!= 0) {
3114 kbuf
= drm_alloc(cmdbuf
.bufsz
, DRM_MEM_DRIVER
);
3117 if (DRM_COPY_FROM_USER(kbuf
, (void *)cmdbuf
.buf
,
3119 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
3125 orig_nbox
= cmdbuf
.nbox
;
3127 if (dev_priv
->microcode_version
== UCODE_R300
) {
3129 temp
= r300_do_cp_cmdbuf(dev
, fpriv
, &cmdbuf
);
3131 if (orig_bufsz
!= 0)
3132 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
3137 /* microcode_version != r300 */
3138 while (cmdbuf
.bufsz
>= sizeof (header
)) {
3140 header
.i
= *(int *)(uintptr_t)cmdbuf
.buf
;
3141 cmdbuf
.buf
+= sizeof (header
);
3142 cmdbuf
.bufsz
-= sizeof (header
);
3144 switch (header
.header
.cmd_type
) {
3145 case RADEON_CMD_PACKET
:
3146 DRM_DEBUG("RADEON_CMD_PACKET\n");
3147 if (radeon_emit_packets
3148 (dev_priv
, fpriv
, header
, &cmdbuf
)) {
3149 DRM_ERROR("radeon_emit_packets failed\n");
3154 case RADEON_CMD_SCALARS
:
3155 DRM_DEBUG("RADEON_CMD_SCALARS\n");
3156 if (radeon_emit_scalars(dev_priv
, header
, &cmdbuf
)) {
3157 DRM_ERROR("radeon_emit_scalars failed\n");
3162 case RADEON_CMD_VECTORS
:
3163 DRM_DEBUG("RADEON_CMD_VECTORS\n");
3164 if (radeon_emit_vectors(dev_priv
, header
, &cmdbuf
)) {
3165 DRM_ERROR("radeon_emit_vectors failed\n");
3170 case RADEON_CMD_DMA_DISCARD
:
3171 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
3172 idx
= header
.dma
.buf_idx
;
3173 if (idx
< 0 || idx
>= dma
->buf_count
) {
3174 DRM_ERROR("buffer index %d (of %d max)\n",
3175 idx
, dma
->buf_count
- 1);
3179 buf
= dma
->buflist
[idx
];
3180 if (buf
->filp
!= fpriv
|| buf
->pending
) {
3181 DRM_ERROR("bad buffer %p %p %d\n",
3182 buf
->filp
, fpriv
, buf
->pending
);
3186 radeon_cp_discard_buffer(dev
, buf
);
3189 case RADEON_CMD_PACKET3
:
3190 DRM_DEBUG("RADEON_CMD_PACKET3\n");
3191 if (radeon_emit_packet3(dev
, fpriv
, &cmdbuf
)) {
3192 DRM_ERROR("radeon_emit_packet3 failed\n");
3197 case RADEON_CMD_PACKET3_CLIP
:
3198 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
3199 if (radeon_emit_packet3_cliprect
3200 (dev
, fpriv
, &cmdbuf
, orig_nbox
)) {
3201 DRM_ERROR("radeon_emit_packet3_clip failed\n");
3206 case RADEON_CMD_SCALARS2
:
3207 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
3208 if (radeon_emit_scalars2(dev_priv
, header
, &cmdbuf
)) {
3209 DRM_ERROR("radeon_emit_scalars2 failed\n");
3214 case RADEON_CMD_WAIT
:
3215 DRM_DEBUG("RADEON_CMD_WAIT\n");
3216 if (radeon_emit_wait(dev
, header
.wait
.flags
)) {
3217 DRM_ERROR("radeon_emit_wait failed\n");
3221 case RADEON_CMD_VECLINEAR
:
3222 DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
3223 if (radeon_emit_veclinear(dev_priv
, header
, &cmdbuf
)) {
3224 DRM_ERROR("radeon_emit_veclinear failed\n");
3230 DRM_ERROR("bad cmd_type %d at %p\n",
3231 header
.header
.cmd_type
,
3232 cmdbuf
.buf
- sizeof (header
));
3237 if (orig_bufsz
!= 0)
3238 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
3244 if (orig_bufsz
!= 0)
3245 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
3250 static int radeon_cp_getparam(DRM_IOCTL_ARGS
)
3253 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3254 drm_radeon_getparam_t param
;
3258 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
3262 #ifdef _MULTI_DATAMODEL
3263 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
3264 drm_radeon_getparam_32_t param32
;
3266 DRM_COPYFROM_WITH_RETURN(¶m32
,
3267 (drm_radeon_getparam_32_t
*)data
, sizeof (param32
));
3268 param
.param
= param32
.param
;
3269 param
.value
= (void *)(uintptr_t)param32
.value
;
3272 DRM_COPYFROM_WITH_RETURN(¶m
,
3273 (drm_radeon_getparam_t
*)data
, sizeof (param
));
3274 #ifdef _MULTI_DATAMODEL
3277 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID
);
3279 switch (param
.param
) {
3280 case RADEON_PARAM_GART_BUFFER_OFFSET
:
3281 value
= dev_priv
->gart_buffers_offset
;
3283 case RADEON_PARAM_LAST_FRAME
:
3284 dev_priv
->stats
.last_frame_reads
++;
3285 value
= GET_SCRATCH(0);
3287 case RADEON_PARAM_LAST_DISPATCH
:
3288 value
= GET_SCRATCH(1);
3290 case RADEON_PARAM_LAST_CLEAR
:
3291 dev_priv
->stats
.last_clear_reads
++;
3292 value
= GET_SCRATCH(2);
3294 case RADEON_PARAM_IRQ_NR
:
3297 case RADEON_PARAM_GART_BASE
:
3298 value
= dev_priv
->gart_vm_start
;
3300 case RADEON_PARAM_REGISTER_HANDLE
:
3301 value
= dev_priv
->mmio
->offset
;
3303 case RADEON_PARAM_STATUS_HANDLE
:
3304 value
= dev_priv
->ring_rptr_offset
;
3308 * This ioctl() doesn't work on 64-bit platforms because
3309 * hw_lock is a pointer which can't fit into an int-sized
3310 * variable. According to Michel Dänzer, the ioctl) is
3311 * only used on embedded platforms, so not supporting it
3312 * shouldn't be a problem. If the same functionality is
3313 * needed on 64-bit platforms, a new ioctl() would have
3314 * to be added, so backwards-compatibility for the embedded
3315 * platforms can be maintained. --davidm 4-Feb-2004.
3317 case RADEON_PARAM_SAREA_HANDLE
:
3318 /* The lock is the first dword in the sarea. */
3319 value
= (long)dev
->lock
.hw_lock
;
3322 case RADEON_PARAM_GART_TEX_HANDLE
:
3323 value
= dev_priv
->gart_textures_offset
;
3325 case RADEON_PARAM_SCRATCH_OFFSET
:
3326 if (!dev_priv
->writeback_works
)
3328 value
= RADEON_SCRATCH_REG_OFFSET
;
3331 case RADEON_PARAM_CARD_TYPE
:
3332 if (dev_priv
->flags
& RADEON_IS_PCIE
)
3333 value
= RADEON_CARD_PCIE
;
3334 else if (dev_priv
->flags
& RADEON_IS_AGP
)
3335 value
= RADEON_CARD_AGP
;
3337 value
= RADEON_CARD_PCI
;
3339 case RADEON_PARAM_VBLANK_CRTC
:
3340 value
= radeon_vblank_crtc_get(dev
);
3346 if (DRM_COPY_TO_USER(param
.value
, &value
, sizeof (int))) {
3347 DRM_ERROR("copy_to_user\n");
3354 static int radeon_cp_setparam(DRM_IOCTL_ARGS
)
3357 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3358 drm_radeon_setparam_t sp
;
3359 struct drm_radeon_driver_file_fields
*radeon_priv
;
3362 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
3366 #ifdef _MULTI_DATAMODEL
3367 if (ddi_model_convert_from(mode
& FMODELS
) == DDI_MODEL_ILP32
) {
3368 drm_radeon_setparam_32_t sp32
;
3370 DRM_COPYFROM_WITH_RETURN(&sp32
, (void *) data
, sizeof (sp32
));
3371 sp
.param
= sp32
.param
;
3372 sp
.value
= sp32
.value
;
3375 DRM_COPYFROM_WITH_RETURN(&sp
, (void *) data
, sizeof (sp
));
3376 #ifdef _MULTI_DATAMODEL
3380 case RADEON_SETPARAM_FB_LOCATION
:
3381 radeon_priv
= fpriv
->driver_priv
;
3382 radeon_priv
->radeon_fb_delta
= dev_priv
->fb_location
- sp
.value
;
3384 case RADEON_SETPARAM_SWITCH_TILING
:
3385 if (sp
.value
== 0) {
3386 DRM_DEBUG("color tiling disabled\n");
3387 dev_priv
->front_pitch_offset
&= ~RADEON_DST_TILE_MACRO
;
3388 dev_priv
->back_pitch_offset
&= ~RADEON_DST_TILE_MACRO
;
3389 dev_priv
->sarea_priv
->tiling_enabled
= 0;
3390 } else if (sp
.value
== 1) {
3391 DRM_DEBUG("color tiling enabled\n");
3392 dev_priv
->front_pitch_offset
|= RADEON_DST_TILE_MACRO
;
3393 dev_priv
->back_pitch_offset
|= RADEON_DST_TILE_MACRO
;
3394 dev_priv
->sarea_priv
->tiling_enabled
= 1;
3397 case RADEON_SETPARAM_PCIGART_LOCATION
:
3398 dev_priv
->pcigart_offset
= (unsigned long)sp
.value
;
3400 case RADEON_SETPARAM_NEW_MEMMAP
:
3401 dev_priv
->new_memmap
= (int)sp
.value
;
3403 case RADEON_SETPARAM_VBLANK_CRTC
:
3404 return (radeon_vblank_crtc_set(dev
, sp
.value
));
3406 DRM_DEBUG("Invalid parameter %d\n", sp
.param
);
3414 * When a client dies:
3415 * - Check for and clean up flipped page state
3416 * - Free any alloced GART memory.
3417 * - Free any alloced radeon surfaces.
3419 * DRM infrastructure takes care of reclaiming dma buffers.
3422 radeon_driver_preclose(drm_device_t
*dev
, drm_file_t
*filp
)
3424 if (dev
->dev_private
) {
3425 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3426 if (dev_priv
->page_flipping
) {
3427 (void) radeon_do_cleanup_pageflip(dev
);
3429 radeon_mem_release(filp
, dev_priv
->gart_heap
);
3430 radeon_mem_release(filp
, dev_priv
->fb_heap
);
3431 radeon_surfaces_release(filp
, dev_priv
);
3436 radeon_driver_lastclose(drm_device_t
*dev
)
3438 radeon_do_release(dev
);
3442 radeon_driver_open(drm_device_t
*dev
, drm_file_t
*filp_priv
)
3444 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3445 struct drm_radeon_driver_file_fields
*radeon_priv
;
3448 (struct drm_radeon_driver_file_fields
*)
3449 drm_alloc(sizeof (*radeon_priv
), DRM_MEM_FILES
);
3454 filp_priv
->driver_priv
= radeon_priv
;
3457 radeon_priv
->radeon_fb_delta
= dev_priv
->fb_location
;
3459 radeon_priv
->radeon_fb_delta
= 0;
3465 radeon_driver_postclose(drm_device_t
*dev
, drm_file_t
*filp_priv
)
3467 struct drm_radeon_driver_file_fields
*radeon_priv
=
3468 filp_priv
->driver_priv
;
3470 drm_free(radeon_priv
, sizeof (* radeon_priv
), DRM_MEM_FILES
);
3473 drm_ioctl_desc_t radeon_ioctls
[] = {
3474 [DRM_IOCTL_NR(DRM_RADEON_CP_INIT
)] =
3475 {radeon_cp_init
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
},
3476 [DRM_IOCTL_NR(DRM_RADEON_CP_START
)] =
3477 {radeon_cp_start
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
},
3478 [DRM_IOCTL_NR(DRM_RADEON_CP_STOP
)] =
3479 {radeon_cp_stop
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
},
3480 [DRM_IOCTL_NR(DRM_RADEON_CP_RESET
)] =
3481 {radeon_cp_reset
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
},
3482 [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE
)] =
3483 {radeon_cp_idle
, DRM_AUTH
},
3484 [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME
)] =
3485 {radeon_cp_resume
, DRM_AUTH
},
3486 [DRM_IOCTL_NR(DRM_RADEON_RESET
)] =
3487 {radeon_engine_reset
, DRM_AUTH
},
3488 [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN
)] =
3489 {radeon_fullscreen
, DRM_AUTH
},
3490 [DRM_IOCTL_NR(DRM_RADEON_SWAP
)] =
3491 {radeon_cp_swap
, DRM_AUTH
},
3492 [DRM_IOCTL_NR(DRM_RADEON_CLEAR
)] =
3493 {radeon_cp_clear
, DRM_AUTH
},
3494 [DRM_IOCTL_NR(DRM_RADEON_VERTEX
)] =
3495 {radeon_cp_vertex
, DRM_AUTH
},
3496 [DRM_IOCTL_NR(DRM_RADEON_INDICES
)] =
3497 {radeon_cp_indices
, DRM_AUTH
},
3498 [DRM_IOCTL_NR(DRM_RADEON_TEXTURE
)] =
3499 {radeon_cp_texture
, DRM_AUTH
},
3500 [DRM_IOCTL_NR(DRM_RADEON_STIPPLE
)] =
3501 {radeon_cp_stipple
, DRM_AUTH
},
3502 [DRM_IOCTL_NR(DRM_RADEON_INDIRECT
)] =
3503 {radeon_cp_indirect
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
},
3504 [DRM_IOCTL_NR(DRM_RADEON_VERTEX2
)] =
3505 {radeon_cp_vertex2
, DRM_AUTH
},
3506 [DRM_IOCTL_NR(DRM_RADEON_CMDBUF
)] =
3507 {radeon_cp_cmdbuf
, DRM_AUTH
},
3508 [DRM_IOCTL_NR(DRM_RADEON_GETPARAM
)] =
3509 {radeon_cp_getparam
, DRM_AUTH
},
3510 [DRM_IOCTL_NR(DRM_RADEON_FLIP
)] =
3511 {radeon_cp_flip
, DRM_AUTH
},
3512 [DRM_IOCTL_NR(DRM_RADEON_ALLOC
)] =
3513 {radeon_mem_alloc
, DRM_AUTH
},
3514 [DRM_IOCTL_NR(DRM_RADEON_FREE
)] =
3515 {radeon_mem_free
, DRM_AUTH
},
3516 [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP
)] =
3517 {radeon_mem_init_heap
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
},
3518 [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT
)] =
3519 {radeon_irq_emit
, DRM_AUTH
},
3520 [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT
)] =
3521 {radeon_irq_wait
, DRM_AUTH
},
3522 [DRM_IOCTL_NR(DRM_RADEON_SETPARAM
)] =
3523 {radeon_cp_setparam
, DRM_AUTH
},
3524 [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC
)] =
3525 {radeon_surface_alloc
, DRM_AUTH
},
3526 [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE
)] =
3527 {radeon_surface_free
, DRM_AUTH
}
3530 int radeon_max_ioctl
= DRM_ARRAY_SIZE(radeon_ioctls
);