1 /* radeon_state.c -- State support for Radeon -*- linux-c -*-
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * Gareth Hughes <gareth@valinux.com>
27 * Kevin E. Martin <martin@valinux.com>
32 #include "drm_sarea.h"
33 #include "radeon_drm.h"
34 #include "radeon_drv.h"
36 /* ================================================================
37 * Helper functions for client state checking and fixup
40 static __inline__
int radeon_check_and_fixup_offset(drm_radeon_private_t
*
42 drm_file_t
* filp_priv
,
46 struct drm_radeon_driver_file_fields
*radeon_priv
;
48 if (off
>= dev_priv
->fb_location
&&
49 off
< (dev_priv
->gart_vm_start
+ dev_priv
->gart_size
))
52 radeon_priv
= filp_priv
->driver_priv
;
53 off
+= radeon_priv
->radeon_fb_delta
;
55 DRM_DEBUG("offset fixed up to 0x%x\n", off
);
57 if (off
< dev_priv
->fb_location
||
58 off
>= (dev_priv
->gart_vm_start
+ dev_priv
->gart_size
))
59 return DRM_ERR(EINVAL
);
66 static __inline__
int radeon_check_and_fixup_packets(drm_radeon_private_t
*
68 drm_file_t
* filp_priv
,
69 int id
, u32 __user
* data
)
73 case RADEON_EMIT_PP_MISC
:
74 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
75 &data
[(RADEON_RB3D_DEPTHOFFSET
79 DRM_ERROR("Invalid depth buffer offset\n");
80 return DRM_ERR(EINVAL
);
84 case RADEON_EMIT_PP_CNTL
:
85 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
86 &data
[(RADEON_RB3D_COLOROFFSET
90 DRM_ERROR("Invalid colour buffer offset\n");
91 return DRM_ERR(EINVAL
);
95 case R200_EMIT_PP_TXOFFSET_0
:
96 case R200_EMIT_PP_TXOFFSET_1
:
97 case R200_EMIT_PP_TXOFFSET_2
:
98 case R200_EMIT_PP_TXOFFSET_3
:
99 case R200_EMIT_PP_TXOFFSET_4
:
100 case R200_EMIT_PP_TXOFFSET_5
:
101 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
103 DRM_ERROR("Invalid R200 texture offset\n");
104 return DRM_ERR(EINVAL
);
108 case RADEON_EMIT_PP_TXFILTER_0
:
109 case RADEON_EMIT_PP_TXFILTER_1
:
110 case RADEON_EMIT_PP_TXFILTER_2
:
111 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
112 &data
[(RADEON_PP_TXOFFSET_0
114 RADEON_PP_TXFILTER_0
) /
116 DRM_ERROR("Invalid R100 texture offset\n");
117 return DRM_ERR(EINVAL
);
121 case R200_EMIT_PP_CUBIC_OFFSETS_0
:
122 case R200_EMIT_PP_CUBIC_OFFSETS_1
:
123 case R200_EMIT_PP_CUBIC_OFFSETS_2
:
124 case R200_EMIT_PP_CUBIC_OFFSETS_3
:
125 case R200_EMIT_PP_CUBIC_OFFSETS_4
:
126 case R200_EMIT_PP_CUBIC_OFFSETS_5
:{
128 for (i
= 0; i
< 5; i
++) {
129 if (radeon_check_and_fixup_offset
130 (dev_priv
, filp_priv
, &data
[i
])) {
132 ("Invalid R200 cubic texture offset\n");
133 return DRM_ERR(EINVAL
);
139 case RADEON_EMIT_PP_CUBIC_OFFSETS_T0
:
140 case RADEON_EMIT_PP_CUBIC_OFFSETS_T1
:
141 case RADEON_EMIT_PP_CUBIC_OFFSETS_T2
:{
143 for (i
= 0; i
< 5; i
++) {
144 if (radeon_check_and_fixup_offset(dev_priv
,
148 ("Invalid R100 cubic texture offset\n");
149 return DRM_ERR(EINVAL
);
155 case RADEON_EMIT_RB3D_COLORPITCH
:
156 case RADEON_EMIT_RE_LINE_PATTERN
:
157 case RADEON_EMIT_SE_LINE_WIDTH
:
158 case RADEON_EMIT_PP_LUM_MATRIX
:
159 case RADEON_EMIT_PP_ROT_MATRIX_0
:
160 case RADEON_EMIT_RB3D_STENCILREFMASK
:
161 case RADEON_EMIT_SE_VPORT_XSCALE
:
162 case RADEON_EMIT_SE_CNTL
:
163 case RADEON_EMIT_SE_CNTL_STATUS
:
164 case RADEON_EMIT_RE_MISC
:
165 case RADEON_EMIT_PP_BORDER_COLOR_0
:
166 case RADEON_EMIT_PP_BORDER_COLOR_1
:
167 case RADEON_EMIT_PP_BORDER_COLOR_2
:
168 case RADEON_EMIT_SE_ZBIAS_FACTOR
:
169 case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT
:
170 case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED
:
171 case R200_EMIT_PP_TXCBLEND_0
:
172 case R200_EMIT_PP_TXCBLEND_1
:
173 case R200_EMIT_PP_TXCBLEND_2
:
174 case R200_EMIT_PP_TXCBLEND_3
:
175 case R200_EMIT_PP_TXCBLEND_4
:
176 case R200_EMIT_PP_TXCBLEND_5
:
177 case R200_EMIT_PP_TXCBLEND_6
:
178 case R200_EMIT_PP_TXCBLEND_7
:
179 case R200_EMIT_TCL_LIGHT_MODEL_CTL_0
:
180 case R200_EMIT_TFACTOR_0
:
181 case R200_EMIT_VTX_FMT_0
:
182 case R200_EMIT_VAP_CTL
:
183 case R200_EMIT_MATRIX_SELECT_0
:
184 case R200_EMIT_TEX_PROC_CTL_2
:
185 case R200_EMIT_TCL_UCP_VERT_BLEND_CTL
:
186 case R200_EMIT_PP_TXFILTER_0
:
187 case R200_EMIT_PP_TXFILTER_1
:
188 case R200_EMIT_PP_TXFILTER_2
:
189 case R200_EMIT_PP_TXFILTER_3
:
190 case R200_EMIT_PP_TXFILTER_4
:
191 case R200_EMIT_PP_TXFILTER_5
:
192 case R200_EMIT_VTE_CNTL
:
193 case R200_EMIT_OUTPUT_VTX_COMP_SEL
:
194 case R200_EMIT_PP_TAM_DEBUG3
:
195 case R200_EMIT_PP_CNTL_X
:
196 case R200_EMIT_RB3D_DEPTHXY_OFFSET
:
197 case R200_EMIT_RE_AUX_SCISSOR_CNTL
:
198 case R200_EMIT_RE_SCISSOR_TL_0
:
199 case R200_EMIT_RE_SCISSOR_TL_1
:
200 case R200_EMIT_RE_SCISSOR_TL_2
:
201 case R200_EMIT_SE_VAP_CNTL_STATUS
:
202 case R200_EMIT_SE_VTX_STATE_CNTL
:
203 case R200_EMIT_RE_POINTSIZE
:
204 case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0
:
205 case R200_EMIT_PP_CUBIC_FACES_0
:
206 case R200_EMIT_PP_CUBIC_FACES_1
:
207 case R200_EMIT_PP_CUBIC_FACES_2
:
208 case R200_EMIT_PP_CUBIC_FACES_3
:
209 case R200_EMIT_PP_CUBIC_FACES_4
:
210 case R200_EMIT_PP_CUBIC_FACES_5
:
211 case RADEON_EMIT_PP_TEX_SIZE_0
:
212 case RADEON_EMIT_PP_TEX_SIZE_1
:
213 case RADEON_EMIT_PP_TEX_SIZE_2
:
214 case R200_EMIT_RB3D_BLENDCOLOR
:
215 case R200_EMIT_TCL_POINT_SPRITE_CNTL
:
216 case RADEON_EMIT_PP_CUBIC_FACES_0
:
217 case RADEON_EMIT_PP_CUBIC_FACES_1
:
218 case RADEON_EMIT_PP_CUBIC_FACES_2
:
219 case R200_EMIT_PP_TRI_PERF_CNTL
:
220 case R200_EMIT_PP_AFS_0
:
221 case R200_EMIT_PP_AFS_1
:
222 case R200_EMIT_ATF_TFACTOR
:
223 case R200_EMIT_PP_TXCTLALL_0
:
224 case R200_EMIT_PP_TXCTLALL_1
:
225 case R200_EMIT_PP_TXCTLALL_2
:
226 case R200_EMIT_PP_TXCTLALL_3
:
227 case R200_EMIT_PP_TXCTLALL_4
:
228 case R200_EMIT_PP_TXCTLALL_5
:
229 /* These packets don't contain memory offsets */
233 DRM_ERROR("Unknown state packet ID %d\n", id
);
234 return DRM_ERR(EINVAL
);
240 static __inline__
int radeon_check_and_fixup_packet3(drm_radeon_private_t
*
242 drm_file_t
* filp_priv
,
243 drm_radeon_cmd_buffer_t
*
247 u32
*cmd
= (u32
*) cmdbuf
->buf
;
249 *cmdsz
= 2 + ((cmd
[0] & RADEON_CP_PACKET_COUNT_MASK
) >> 16);
251 if ((cmd
[0] & 0xc0000000) != RADEON_CP_PACKET3
) {
252 DRM_ERROR("Not a type 3 packet\n");
253 return DRM_ERR(EINVAL
);
256 if (4 * *cmdsz
> cmdbuf
->bufsz
) {
257 DRM_ERROR("Packet size larger than size of data provided\n");
258 return DRM_ERR(EINVAL
);
261 /* Check client state and fix it up if necessary */
262 if (cmd
[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */
265 if (cmd
[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
266 | RADEON_GMC_DST_PITCH_OFFSET_CNTL
)) {
267 offset
= cmd
[2] << 10;
268 if (radeon_check_and_fixup_offset
269 (dev_priv
, filp_priv
, &offset
)) {
270 DRM_ERROR("Invalid first packet offset\n");
271 return DRM_ERR(EINVAL
);
273 cmd
[2] = (cmd
[2] & 0xffc00000) | offset
>> 10;
276 if ((cmd
[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL
) &&
277 (cmd
[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL
)) {
278 offset
= cmd
[3] << 10;
279 if (radeon_check_and_fixup_offset
280 (dev_priv
, filp_priv
, &offset
)) {
281 DRM_ERROR("Invalid second packet offset\n");
282 return DRM_ERR(EINVAL
);
284 cmd
[3] = (cmd
[3] & 0xffc00000) | offset
>> 10;
291 /* ================================================================
292 * CP hardware state programming functions
295 static __inline__
void radeon_emit_clip_rect(drm_radeon_private_t
* dev_priv
,
296 drm_clip_rect_t
* box
)
300 DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
301 box
->x1
, box
->y1
, box
->x2
, box
->y2
);
304 OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT
, 0));
305 OUT_RING((box
->y1
<< 16) | box
->x1
);
306 OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT
, 0));
307 OUT_RING(((box
->y2
- 1) << 16) | (box
->x2
- 1));
313 static int radeon_emit_state(drm_radeon_private_t
* dev_priv
,
314 drm_file_t
* filp_priv
,
315 drm_radeon_context_regs_t
* ctx
,
316 drm_radeon_texture_regs_t
* tex
,
320 DRM_DEBUG("dirty=0x%08x\n", dirty
);
322 if (dirty
& RADEON_UPLOAD_CONTEXT
) {
323 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
324 &ctx
->rb3d_depthoffset
)) {
325 DRM_ERROR("Invalid depth buffer offset\n");
326 return DRM_ERR(EINVAL
);
329 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
330 &ctx
->rb3d_coloroffset
)) {
331 DRM_ERROR("Invalid depth buffer offset\n");
332 return DRM_ERR(EINVAL
);
336 OUT_RING(CP_PACKET0(RADEON_PP_MISC
, 6));
337 OUT_RING(ctx
->pp_misc
);
338 OUT_RING(ctx
->pp_fog_color
);
339 OUT_RING(ctx
->re_solid_color
);
340 OUT_RING(ctx
->rb3d_blendcntl
);
341 OUT_RING(ctx
->rb3d_depthoffset
);
342 OUT_RING(ctx
->rb3d_depthpitch
);
343 OUT_RING(ctx
->rb3d_zstencilcntl
);
344 OUT_RING(CP_PACKET0(RADEON_PP_CNTL
, 2));
345 OUT_RING(ctx
->pp_cntl
);
346 OUT_RING(ctx
->rb3d_cntl
);
347 OUT_RING(ctx
->rb3d_coloroffset
);
348 OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH
, 0));
349 OUT_RING(ctx
->rb3d_colorpitch
);
353 if (dirty
& RADEON_UPLOAD_VERTFMT
) {
355 OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT
, 0));
356 OUT_RING(ctx
->se_coord_fmt
);
360 if (dirty
& RADEON_UPLOAD_LINE
) {
362 OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN
, 1));
363 OUT_RING(ctx
->re_line_pattern
);
364 OUT_RING(ctx
->re_line_state
);
365 OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH
, 0));
366 OUT_RING(ctx
->se_line_width
);
370 if (dirty
& RADEON_UPLOAD_BUMPMAP
) {
372 OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX
, 0));
373 OUT_RING(ctx
->pp_lum_matrix
);
374 OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0
, 1));
375 OUT_RING(ctx
->pp_rot_matrix_0
);
376 OUT_RING(ctx
->pp_rot_matrix_1
);
380 if (dirty
& RADEON_UPLOAD_MASKS
) {
382 OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK
, 2));
383 OUT_RING(ctx
->rb3d_stencilrefmask
);
384 OUT_RING(ctx
->rb3d_ropcntl
);
385 OUT_RING(ctx
->rb3d_planemask
);
389 if (dirty
& RADEON_UPLOAD_VIEWPORT
) {
391 OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE
, 5));
392 OUT_RING(ctx
->se_vport_xscale
);
393 OUT_RING(ctx
->se_vport_xoffset
);
394 OUT_RING(ctx
->se_vport_yscale
);
395 OUT_RING(ctx
->se_vport_yoffset
);
396 OUT_RING(ctx
->se_vport_zscale
);
397 OUT_RING(ctx
->se_vport_zoffset
);
401 if (dirty
& RADEON_UPLOAD_SETUP
) {
403 OUT_RING(CP_PACKET0(RADEON_SE_CNTL
, 0));
404 OUT_RING(ctx
->se_cntl
);
405 OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS
, 0));
406 OUT_RING(ctx
->se_cntl_status
);
410 if (dirty
& RADEON_UPLOAD_MISC
) {
412 OUT_RING(CP_PACKET0(RADEON_RE_MISC
, 0));
413 OUT_RING(ctx
->re_misc
);
417 if (dirty
& RADEON_UPLOAD_TEX0
) {
418 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
419 &tex
[0].pp_txoffset
)) {
420 DRM_ERROR("Invalid texture offset for unit 0\n");
421 return DRM_ERR(EINVAL
);
425 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0
, 5));
426 OUT_RING(tex
[0].pp_txfilter
);
427 OUT_RING(tex
[0].pp_txformat
);
428 OUT_RING(tex
[0].pp_txoffset
);
429 OUT_RING(tex
[0].pp_txcblend
);
430 OUT_RING(tex
[0].pp_txablend
);
431 OUT_RING(tex
[0].pp_tfactor
);
432 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0
, 0));
433 OUT_RING(tex
[0].pp_border_color
);
437 if (dirty
& RADEON_UPLOAD_TEX1
) {
438 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
439 &tex
[1].pp_txoffset
)) {
440 DRM_ERROR("Invalid texture offset for unit 1\n");
441 return DRM_ERR(EINVAL
);
445 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1
, 5));
446 OUT_RING(tex
[1].pp_txfilter
);
447 OUT_RING(tex
[1].pp_txformat
);
448 OUT_RING(tex
[1].pp_txoffset
);
449 OUT_RING(tex
[1].pp_txcblend
);
450 OUT_RING(tex
[1].pp_txablend
);
451 OUT_RING(tex
[1].pp_tfactor
);
452 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1
, 0));
453 OUT_RING(tex
[1].pp_border_color
);
457 if (dirty
& RADEON_UPLOAD_TEX2
) {
458 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
,
459 &tex
[2].pp_txoffset
)) {
460 DRM_ERROR("Invalid texture offset for unit 2\n");
461 return DRM_ERR(EINVAL
);
465 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2
, 5));
466 OUT_RING(tex
[2].pp_txfilter
);
467 OUT_RING(tex
[2].pp_txformat
);
468 OUT_RING(tex
[2].pp_txoffset
);
469 OUT_RING(tex
[2].pp_txcblend
);
470 OUT_RING(tex
[2].pp_txablend
);
471 OUT_RING(tex
[2].pp_tfactor
);
472 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2
, 0));
473 OUT_RING(tex
[2].pp_border_color
);
482 static int radeon_emit_state2(drm_radeon_private_t
* dev_priv
,
483 drm_file_t
* filp_priv
,
484 drm_radeon_state_t
* state
)
488 if (state
->dirty
& RADEON_UPLOAD_ZBIAS
) {
490 OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR
, 1));
491 OUT_RING(state
->context2
.se_zbias_factor
);
492 OUT_RING(state
->context2
.se_zbias_constant
);
496 return radeon_emit_state(dev_priv
, filp_priv
, &state
->context
,
497 state
->tex
, state
->dirty
);
500 /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
501 * 1.3 cmdbuffers allow all previous state to be updated as well as
502 * the tcl scalar and vector areas.
508 } packet
[RADEON_MAX_STATE_PACKETS
] = {
509 {RADEON_PP_MISC
, 7, "RADEON_PP_MISC"},
510 {RADEON_PP_CNTL
, 3, "RADEON_PP_CNTL"},
511 {RADEON_RB3D_COLORPITCH
, 1, "RADEON_RB3D_COLORPITCH"},
512 {RADEON_RE_LINE_PATTERN
, 2, "RADEON_RE_LINE_PATTERN"},
513 {RADEON_SE_LINE_WIDTH
, 1, "RADEON_SE_LINE_WIDTH"},
514 {RADEON_PP_LUM_MATRIX
, 1, "RADEON_PP_LUM_MATRIX"},
515 {RADEON_PP_ROT_MATRIX_0
, 2, "RADEON_PP_ROT_MATRIX_0"},
516 {RADEON_RB3D_STENCILREFMASK
, 3, "RADEON_RB3D_STENCILREFMASK"},
517 {RADEON_SE_VPORT_XSCALE
, 6, "RADEON_SE_VPORT_XSCALE"},
518 {RADEON_SE_CNTL
, 2, "RADEON_SE_CNTL"},
519 {RADEON_SE_CNTL_STATUS
, 1, "RADEON_SE_CNTL_STATUS"},
520 {RADEON_RE_MISC
, 1, "RADEON_RE_MISC"},
521 {RADEON_PP_TXFILTER_0
, 6, "RADEON_PP_TXFILTER_0"},
522 {RADEON_PP_BORDER_COLOR_0
, 1, "RADEON_PP_BORDER_COLOR_0"},
523 {RADEON_PP_TXFILTER_1
, 6, "RADEON_PP_TXFILTER_1"},
524 {RADEON_PP_BORDER_COLOR_1
, 1, "RADEON_PP_BORDER_COLOR_1"},
525 {RADEON_PP_TXFILTER_2
, 6, "RADEON_PP_TXFILTER_2"},
526 {RADEON_PP_BORDER_COLOR_2
, 1, "RADEON_PP_BORDER_COLOR_2"},
527 {RADEON_SE_ZBIAS_FACTOR
, 2, "RADEON_SE_ZBIAS_FACTOR"},
528 {RADEON_SE_TCL_OUTPUT_VTX_FMT
, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
529 {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
, 17,
530 "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
531 {R200_PP_TXCBLEND_0
, 4, "R200_PP_TXCBLEND_0"},
532 {R200_PP_TXCBLEND_1
, 4, "R200_PP_TXCBLEND_1"},
533 {R200_PP_TXCBLEND_2
, 4, "R200_PP_TXCBLEND_2"},
534 {R200_PP_TXCBLEND_3
, 4, "R200_PP_TXCBLEND_3"},
535 {R200_PP_TXCBLEND_4
, 4, "R200_PP_TXCBLEND_4"},
536 {R200_PP_TXCBLEND_5
, 4, "R200_PP_TXCBLEND_5"},
537 {R200_PP_TXCBLEND_6
, 4, "R200_PP_TXCBLEND_6"},
538 {R200_PP_TXCBLEND_7
, 4, "R200_PP_TXCBLEND_7"},
539 {R200_SE_TCL_LIGHT_MODEL_CTL_0
, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
540 {R200_PP_TFACTOR_0
, 6, "R200_PP_TFACTOR_0"},
541 {R200_SE_VTX_FMT_0
, 4, "R200_SE_VTX_FMT_0"},
542 {R200_SE_VAP_CNTL
, 1, "R200_SE_VAP_CNTL"},
543 {R200_SE_TCL_MATRIX_SEL_0
, 5, "R200_SE_TCL_MATRIX_SEL_0"},
544 {R200_SE_TCL_TEX_PROC_CTL_2
, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
545 {R200_SE_TCL_UCP_VERT_BLEND_CTL
, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
546 {R200_PP_TXFILTER_0
, 6, "R200_PP_TXFILTER_0"},
547 {R200_PP_TXFILTER_1
, 6, "R200_PP_TXFILTER_1"},
548 {R200_PP_TXFILTER_2
, 6, "R200_PP_TXFILTER_2"},
549 {R200_PP_TXFILTER_3
, 6, "R200_PP_TXFILTER_3"},
550 {R200_PP_TXFILTER_4
, 6, "R200_PP_TXFILTER_4"},
551 {R200_PP_TXFILTER_5
, 6, "R200_PP_TXFILTER_5"},
552 {R200_PP_TXOFFSET_0
, 1, "R200_PP_TXOFFSET_0"},
553 {R200_PP_TXOFFSET_1
, 1, "R200_PP_TXOFFSET_1"},
554 {R200_PP_TXOFFSET_2
, 1, "R200_PP_TXOFFSET_2"},
555 {R200_PP_TXOFFSET_3
, 1, "R200_PP_TXOFFSET_3"},
556 {R200_PP_TXOFFSET_4
, 1, "R200_PP_TXOFFSET_4"},
557 {R200_PP_TXOFFSET_5
, 1, "R200_PP_TXOFFSET_5"},
558 {R200_SE_VTE_CNTL
, 1, "R200_SE_VTE_CNTL"},
559 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL
, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
560 {R200_PP_TAM_DEBUG3
, 1, "R200_PP_TAM_DEBUG3"},
561 {R200_PP_CNTL_X
, 1, "R200_PP_CNTL_X"},
562 {R200_RB3D_DEPTHXY_OFFSET
, 1, "R200_RB3D_DEPTHXY_OFFSET"},
563 {R200_RE_AUX_SCISSOR_CNTL
, 1, "R200_RE_AUX_SCISSOR_CNTL"},
564 {R200_RE_SCISSOR_TL_0
, 2, "R200_RE_SCISSOR_TL_0"},
565 {R200_RE_SCISSOR_TL_1
, 2, "R200_RE_SCISSOR_TL_1"},
566 {R200_RE_SCISSOR_TL_2
, 2, "R200_RE_SCISSOR_TL_2"},
567 {R200_SE_VAP_CNTL_STATUS
, 1, "R200_SE_VAP_CNTL_STATUS"},
568 {R200_SE_VTX_STATE_CNTL
, 1, "R200_SE_VTX_STATE_CNTL"},
569 {R200_RE_POINTSIZE
, 1, "R200_RE_POINTSIZE"},
570 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0
, 4,
571 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
572 {R200_PP_CUBIC_FACES_0
, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
573 {R200_PP_CUBIC_OFFSET_F1_0
, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
574 {R200_PP_CUBIC_FACES_1
, 1, "R200_PP_CUBIC_FACES_1"},
575 {R200_PP_CUBIC_OFFSET_F1_1
, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
576 {R200_PP_CUBIC_FACES_2
, 1, "R200_PP_CUBIC_FACES_2"},
577 {R200_PP_CUBIC_OFFSET_F1_2
, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
578 {R200_PP_CUBIC_FACES_3
, 1, "R200_PP_CUBIC_FACES_3"},
579 {R200_PP_CUBIC_OFFSET_F1_3
, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
580 {R200_PP_CUBIC_FACES_4
, 1, "R200_PP_CUBIC_FACES_4"},
581 {R200_PP_CUBIC_OFFSET_F1_4
, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
582 {R200_PP_CUBIC_FACES_5
, 1, "R200_PP_CUBIC_FACES_5"},
583 {R200_PP_CUBIC_OFFSET_F1_5
, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
584 {RADEON_PP_TEX_SIZE_0
, 2, "RADEON_PP_TEX_SIZE_0"},
585 {RADEON_PP_TEX_SIZE_1
, 2, "RADEON_PP_TEX_SIZE_1"},
586 {RADEON_PP_TEX_SIZE_2
, 2, "RADEON_PP_TEX_SIZE_2"},
587 {R200_RB3D_BLENDCOLOR
, 3, "R200_RB3D_BLENDCOLOR"},
588 {R200_SE_TCL_POINT_SPRITE_CNTL
, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
589 {RADEON_PP_CUBIC_FACES_0
, 1, "RADEON_PP_CUBIC_FACES_0"},
590 {RADEON_PP_CUBIC_OFFSET_T0_0
, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
591 {RADEON_PP_CUBIC_FACES_1
, 1, "RADEON_PP_CUBIC_FACES_1"},
592 {RADEON_PP_CUBIC_OFFSET_T1_0
, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
593 {RADEON_PP_CUBIC_FACES_2
, 1, "RADEON_PP_CUBIC_FACES_2"},
594 {RADEON_PP_CUBIC_OFFSET_T2_0
, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
595 {R200_PP_TRI_PERF
, 2, "R200_PP_TRI_PERF"},
596 {R200_PP_AFS_0
, 32, "R200_PP_AFS_0"}, /* 85 */
597 {R200_PP_AFS_1
, 32, "R200_PP_AFS_1"},
598 {R200_PP_TFACTOR_0
, 8, "R200_ATF_TFACTOR"},
599 {R200_PP_TXFILTER_0
, 8, "R200_PP_TXCTLALL_0"},
600 {R200_PP_TXFILTER_1
, 8, "R200_PP_TXCTLALL_1"},
601 {R200_PP_TXFILTER_2
, 8, "R200_PP_TXCTLALL_2"},
602 {R200_PP_TXFILTER_3
, 8, "R200_PP_TXCTLALL_3"},
603 {R200_PP_TXFILTER_4
, 8, "R200_PP_TXCTLALL_4"},
604 {R200_PP_TXFILTER_5
, 8, "R200_PP_TXCTLALL_5"},
607 /* ================================================================
608 * Performance monitoring functions
611 static void radeon_clear_box(drm_radeon_private_t
* dev_priv
,
612 int x
, int y
, int w
, int h
, int r
, int g
, int b
)
617 x
+= dev_priv
->sarea_priv
->boxes
[0].x1
;
618 y
+= dev_priv
->sarea_priv
->boxes
[0].y1
;
620 switch (dev_priv
->color_fmt
) {
621 case RADEON_COLOR_FORMAT_RGB565
:
622 color
= (((r
& 0xf8) << 8) |
623 ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3));
625 case RADEON_COLOR_FORMAT_ARGB8888
:
627 color
= (((0xff) << 24) | (r
<< 16) | (g
<< 8) | b
);
632 RADEON_WAIT_UNTIL_3D_IDLE();
633 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK
, 0));
634 OUT_RING(0xffffffff);
639 OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI
, 4));
640 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
641 RADEON_GMC_BRUSH_SOLID_COLOR
|
642 (dev_priv
->color_fmt
<< 8) |
643 RADEON_GMC_SRC_DATATYPE_COLOR
|
644 RADEON_ROP3_P
| RADEON_GMC_CLR_CMP_CNTL_DIS
);
646 if (dev_priv
->page_flipping
&& dev_priv
->current_page
== 1) {
647 OUT_RING(dev_priv
->front_pitch_offset
);
649 OUT_RING(dev_priv
->back_pitch_offset
);
654 OUT_RING((x
<< 16) | y
);
655 OUT_RING((w
<< 16) | h
);
660 static void radeon_cp_performance_boxes(drm_radeon_private_t
* dev_priv
)
662 /* Collapse various things into a wait flag -- trying to
663 * guess if userspase slept -- better just to have them tell us.
665 if (dev_priv
->stats
.last_frame_reads
> 1 ||
666 dev_priv
->stats
.last_clear_reads
> dev_priv
->stats
.clears
) {
667 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
670 if (dev_priv
->stats
.freelist_loops
) {
671 dev_priv
->stats
.boxes
|= RADEON_BOX_WAIT_IDLE
;
674 /* Purple box for page flipping
676 if (dev_priv
->stats
.boxes
& RADEON_BOX_FLIP
)
677 radeon_clear_box(dev_priv
, 4, 4, 8, 8, 255, 0, 255);
679 /* Red box if we have to wait for idle at any point
681 if (dev_priv
->stats
.boxes
& RADEON_BOX_WAIT_IDLE
)
682 radeon_clear_box(dev_priv
, 16, 4, 8, 8, 255, 0, 0);
684 /* Blue box: lost context?
687 /* Yellow box for texture swaps
689 if (dev_priv
->stats
.boxes
& RADEON_BOX_TEXTURE_LOAD
)
690 radeon_clear_box(dev_priv
, 40, 4, 8, 8, 255, 255, 0);
692 /* Green box if hardware never idles (as far as we can tell)
694 if (!(dev_priv
->stats
.boxes
& RADEON_BOX_DMA_IDLE
))
695 radeon_clear_box(dev_priv
, 64, 4, 8, 8, 0, 255, 0);
697 /* Draw bars indicating number of buffers allocated
698 * (not a great measure, easily confused)
700 if (dev_priv
->stats
.requested_bufs
) {
701 if (dev_priv
->stats
.requested_bufs
> 100)
702 dev_priv
->stats
.requested_bufs
= 100;
704 radeon_clear_box(dev_priv
, 4, 16,
705 dev_priv
->stats
.requested_bufs
, 4,
709 memset(&dev_priv
->stats
, 0, sizeof(dev_priv
->stats
));
713 /* ================================================================
714 * CP command dispatch functions
717 static void radeon_cp_dispatch_clear(drm_device_t
* dev
,
718 drm_radeon_clear_t
* clear
,
719 drm_radeon_clear_rect_t
* depth_boxes
)
721 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
722 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
723 drm_radeon_depth_clear_t
*depth_clear
= &dev_priv
->depth_clear
;
724 int nbox
= sarea_priv
->nbox
;
725 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
726 unsigned int flags
= clear
->flags
;
727 u32 rb3d_cntl
= 0, rb3d_stencilrefmask
= 0;
730 DRM_DEBUG("flags = 0x%x\n", flags
);
732 dev_priv
->stats
.clears
++;
734 if (dev_priv
->page_flipping
&& dev_priv
->current_page
== 1) {
735 unsigned int tmp
= flags
;
737 flags
&= ~(RADEON_FRONT
| RADEON_BACK
);
738 if (tmp
& RADEON_FRONT
)
739 flags
|= RADEON_BACK
;
740 if (tmp
& RADEON_BACK
)
741 flags
|= RADEON_FRONT
;
744 if (flags
& (RADEON_FRONT
| RADEON_BACK
)) {
748 /* Ensure the 3D stream is idle before doing a
749 * 2D fill to clear the front or back buffer.
751 RADEON_WAIT_UNTIL_3D_IDLE();
753 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK
, 0));
754 OUT_RING(clear
->color_mask
);
758 /* Make sure we restore the 3D state next time.
760 dev_priv
->sarea_priv
->ctx_owner
= 0;
762 for (i
= 0; i
< nbox
; i
++) {
765 int w
= pbox
[i
].x2
- x
;
766 int h
= pbox
[i
].y2
- y
;
768 DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
771 if (flags
& RADEON_FRONT
) {
775 (RADEON_CNTL_PAINT_MULTI
, 4));
776 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
777 RADEON_GMC_BRUSH_SOLID_COLOR
|
780 RADEON_GMC_SRC_DATATYPE_COLOR
|
782 RADEON_GMC_CLR_CMP_CNTL_DIS
);
784 OUT_RING(dev_priv
->front_pitch_offset
);
785 OUT_RING(clear
->clear_color
);
787 OUT_RING((x
<< 16) | y
);
788 OUT_RING((w
<< 16) | h
);
793 if (flags
& RADEON_BACK
) {
797 (RADEON_CNTL_PAINT_MULTI
, 4));
798 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
799 RADEON_GMC_BRUSH_SOLID_COLOR
|
802 RADEON_GMC_SRC_DATATYPE_COLOR
|
804 RADEON_GMC_CLR_CMP_CNTL_DIS
);
806 OUT_RING(dev_priv
->back_pitch_offset
);
807 OUT_RING(clear
->clear_color
);
809 OUT_RING((x
<< 16) | y
);
810 OUT_RING((w
<< 16) | h
);
818 /* no docs available, based on reverse engeneering by Stephane Marchesin */
819 if ((flags
& (RADEON_DEPTH
| RADEON_STENCIL
))
820 && (flags
& RADEON_CLEAR_FASTZ
)) {
823 int depthpixperline
=
824 dev_priv
->depth_fmt
==
825 RADEON_DEPTH_FORMAT_16BIT_INT_Z
? (dev_priv
->depth_pitch
/
831 u32 tempRB3D_DEPTHCLEARVALUE
= clear
->clear_depth
|
832 ((clear
->depth_mask
& 0xff) << 24);
834 /* Make sure we restore the 3D state next time.
835 * we haven't touched any "normal" state - still need this?
837 dev_priv
->sarea_priv
->ctx_owner
= 0;
839 if ((dev_priv
->flags
& CHIP_HAS_HIERZ
)
840 && (flags
& RADEON_USE_HIERZ
)) {
841 /* FIXME : reverse engineer that for Rx00 cards */
842 /* FIXME : the mask supposedly contains low-res z values. So can't set
843 just to the max (0xff? or actually 0x3fff?), need to take z clear
844 value into account? */
845 /* pattern seems to work for r100, though get slight
846 rendering errors with glxgears. If hierz is not enabled for r100,
847 only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
848 other ones are ignored, and the same clear mask can be used. That's
849 very different behaviour than R200 which needs different clear mask
850 and different number of tiles to clear if hierz is enabled or not !?!
852 clearmask
= (0xff << 22) | (0xff << 6) | 0x003f003f;
854 /* clear mask : chooses the clearing pattern.
855 rv250: could be used to clear only parts of macrotiles
856 (but that would get really complicated...)?
857 bit 0 and 1 (either or both of them ?!?!) are used to
858 not clear tile (or maybe one of the bits indicates if the tile is
859 compressed or not), bit 2 and 3 to not clear tile 1,...,.
860 Pattern is as follows:
861 | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
862 bits -------------------------------------------------
863 | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
864 rv100: clearmask covers 2x8 4x1 tiles, but one clear still
865 covers 256 pixels ?!?
871 RADEON_WAIT_UNTIL_2D_IDLE();
872 OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE
,
873 tempRB3D_DEPTHCLEARVALUE
);
874 /* what offset is this exactly ? */
875 OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET
, 0);
876 /* need ctlstat, otherwise get some strange black flickering */
877 OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT
,
878 RADEON_RB3D_ZC_FLUSH_ALL
);
881 for (i
= 0; i
< nbox
; i
++) {
882 int tileoffset
, nrtilesx
, nrtilesy
, j
;
883 /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
884 if ((dev_priv
->flags
& CHIP_HAS_HIERZ
)
885 && !(dev_priv
->microcode_version
== UCODE_R200
)) {
886 /* FIXME : figure this out for r200 (when hierz is enabled). Or
887 maybe r200 actually doesn't need to put the low-res z value into
888 the tile cache like r100, but just needs to clear the hi-level z-buffer?
889 Works for R100, both with hierz and without.
890 R100 seems to operate on 2x1 8x8 tiles, but...
891 odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
892 problematic with resolutions which are not 64 pix aligned? */
894 ((pbox
[i
].y1
>> 3) * depthpixperline
+
897 ((pbox
[i
].x2
& ~63) -
898 (pbox
[i
].x1
& ~63)) >> 4;
900 (pbox
[i
].y2
>> 3) - (pbox
[i
].y1
>> 3);
901 for (j
= 0; j
<= nrtilesy
; j
++) {
904 (RADEON_3D_CLEAR_ZMASK
, 2));
906 OUT_RING(tileoffset
* 8);
907 /* the number of tiles to clear */
908 OUT_RING(nrtilesx
+ 4);
909 /* clear mask : chooses the clearing pattern. */
912 tileoffset
+= depthpixperline
>> 6;
914 } else if (dev_priv
->microcode_version
== UCODE_R200
) {
915 /* works for rv250. */
916 /* find first macro tile (8x2 4x4 z-pixels on rv250) */
918 ((pbox
[i
].y1
>> 3) * depthpixperline
+
921 (pbox
[i
].x2
>> 5) - (pbox
[i
].x1
>> 5);
923 (pbox
[i
].y2
>> 3) - (pbox
[i
].y1
>> 3);
924 for (j
= 0; j
<= nrtilesy
; j
++) {
927 (RADEON_3D_CLEAR_ZMASK
, 2));
929 /* judging by the first tile offset needed, could possibly
930 directly address/clear 4x4 tiles instead of 8x2 * 4x4
931 macro tiles, though would still need clear mask for
932 right/bottom if truely 4x4 granularity is desired ? */
933 OUT_RING(tileoffset
* 16);
934 /* the number of tiles to clear */
935 OUT_RING(nrtilesx
+ 1);
936 /* clear mask : chooses the clearing pattern. */
939 tileoffset
+= depthpixperline
>> 5;
941 } else { /* rv 100 */
942 /* rv100 might not need 64 pix alignment, who knows */
943 /* offsets are, hmm, weird */
945 ((pbox
[i
].y1
>> 4) * depthpixperline
+
948 ((pbox
[i
].x2
& ~63) -
949 (pbox
[i
].x1
& ~63)) >> 4;
951 (pbox
[i
].y2
>> 4) - (pbox
[i
].y1
>> 4);
952 for (j
= 0; j
<= nrtilesy
; j
++) {
955 (RADEON_3D_CLEAR_ZMASK
, 2));
956 OUT_RING(tileoffset
* 128);
957 /* the number of tiles to clear */
958 OUT_RING(nrtilesx
+ 4);
959 /* clear mask : chooses the clearing pattern. */
962 tileoffset
+= depthpixperline
>> 6;
967 /* TODO don't always clear all hi-level z tiles */
968 if ((dev_priv
->flags
& CHIP_HAS_HIERZ
)
969 && (dev_priv
->microcode_version
== UCODE_R200
)
970 && (flags
& RADEON_USE_HIERZ
))
971 /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
972 /* FIXME : the mask supposedly contains low-res z values. So can't set
973 just to the max (0xff? or actually 0x3fff?), need to take z clear
974 value into account? */
977 OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ
, 2));
978 OUT_RING(0x0); /* First tile */
980 OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
985 /* We have to clear the depth and/or stencil buffers by
986 * rendering a quad into just those buffers. Thus, we have to
987 * make sure the 3D engine is configured correctly.
989 if ((dev_priv
->microcode_version
== UCODE_R200
) &&
990 (flags
& (RADEON_DEPTH
| RADEON_STENCIL
))) {
995 int tempRB3D_ZSTENCILCNTL
;
996 int tempRB3D_STENCILREFMASK
;
997 int tempRB3D_PLANEMASK
;
1000 int tempSE_VTX_FMT_0
;
1001 int tempSE_VTX_FMT_1
;
1002 int tempSE_VAP_CNTL
;
1003 int tempRE_AUX_SCISSOR_CNTL
;
1008 tempRB3D_CNTL
= depth_clear
->rb3d_cntl
;
1010 tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
1011 tempRB3D_STENCILREFMASK
= 0x0;
1013 tempSE_CNTL
= depth_clear
->se_cntl
;
1017 tempSE_VAP_CNTL
= ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
1019 SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT
));
1021 tempRB3D_PLANEMASK
= 0x0;
1023 tempRE_AUX_SCISSOR_CNTL
= 0x0;
1026 SE_VTE_CNTL__VTX_XY_FMT_MASK
| SE_VTE_CNTL__VTX_Z_FMT_MASK
;
1028 /* Vertex format (X, Y, Z, W) */
1030 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK
|
1031 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK
;
1032 tempSE_VTX_FMT_1
= 0x0;
1035 * Depth buffer specific enables
1037 if (flags
& RADEON_DEPTH
) {
1038 /* Enable depth buffer */
1039 tempRB3D_CNTL
|= RADEON_Z_ENABLE
;
1041 /* Disable depth buffer */
1042 tempRB3D_CNTL
&= ~RADEON_Z_ENABLE
;
1046 * Stencil buffer specific enables
1048 if (flags
& RADEON_STENCIL
) {
1049 tempRB3D_CNTL
|= RADEON_STENCIL_ENABLE
;
1050 tempRB3D_STENCILREFMASK
= clear
->depth_mask
;
1052 tempRB3D_CNTL
&= ~RADEON_STENCIL_ENABLE
;
1053 tempRB3D_STENCILREFMASK
= 0x00000000;
1056 if (flags
& RADEON_USE_COMP_ZBUF
) {
1057 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_COMPRESSION_ENABLE
|
1058 RADEON_Z_DECOMPRESSION_ENABLE
;
1060 if (flags
& RADEON_USE_HIERZ
) {
1061 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_HIERARCHY_ENABLE
;
1065 RADEON_WAIT_UNTIL_2D_IDLE();
1067 OUT_RING_REG(RADEON_PP_CNTL
, tempPP_CNTL
);
1068 OUT_RING_REG(R200_RE_CNTL
, tempRE_CNTL
);
1069 OUT_RING_REG(RADEON_RB3D_CNTL
, tempRB3D_CNTL
);
1070 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL
, tempRB3D_ZSTENCILCNTL
);
1071 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK
,
1072 tempRB3D_STENCILREFMASK
);
1073 OUT_RING_REG(RADEON_RB3D_PLANEMASK
, tempRB3D_PLANEMASK
);
1074 OUT_RING_REG(RADEON_SE_CNTL
, tempSE_CNTL
);
1075 OUT_RING_REG(R200_SE_VTE_CNTL
, tempSE_VTE_CNTL
);
1076 OUT_RING_REG(R200_SE_VTX_FMT_0
, tempSE_VTX_FMT_0
);
1077 OUT_RING_REG(R200_SE_VTX_FMT_1
, tempSE_VTX_FMT_1
);
1078 OUT_RING_REG(R200_SE_VAP_CNTL
, tempSE_VAP_CNTL
);
1079 OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL
, tempRE_AUX_SCISSOR_CNTL
);
1082 /* Make sure we restore the 3D state next time.
1084 dev_priv
->sarea_priv
->ctx_owner
= 0;
1086 for (i
= 0; i
< nbox
; i
++) {
1088 /* Funny that this should be required --
1091 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1094 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2
, 12));
1095 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST
|
1096 RADEON_PRIM_WALK_RING
|
1097 (3 << RADEON_NUM_VERTICES_SHIFT
)));
1098 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1099 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y1
]);
1100 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1101 OUT_RING(0x3f800000);
1102 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1103 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1104 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1105 OUT_RING(0x3f800000);
1106 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X2
]);
1107 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1108 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1109 OUT_RING(0x3f800000);
1112 } else if ((flags
& (RADEON_DEPTH
| RADEON_STENCIL
))) {
1114 int tempRB3D_ZSTENCILCNTL
= depth_clear
->rb3d_zstencilcntl
;
1116 rb3d_cntl
= depth_clear
->rb3d_cntl
;
1118 if (flags
& RADEON_DEPTH
) {
1119 rb3d_cntl
|= RADEON_Z_ENABLE
;
1121 rb3d_cntl
&= ~RADEON_Z_ENABLE
;
1124 if (flags
& RADEON_STENCIL
) {
1125 rb3d_cntl
|= RADEON_STENCIL_ENABLE
;
1126 rb3d_stencilrefmask
= clear
->depth_mask
; /* misnamed field */
1128 rb3d_cntl
&= ~RADEON_STENCIL_ENABLE
;
1129 rb3d_stencilrefmask
= 0x00000000;
1132 if (flags
& RADEON_USE_COMP_ZBUF
) {
1133 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_COMPRESSION_ENABLE
|
1134 RADEON_Z_DECOMPRESSION_ENABLE
;
1136 if (flags
& RADEON_USE_HIERZ
) {
1137 tempRB3D_ZSTENCILCNTL
|= RADEON_Z_HIERARCHY_ENABLE
;
1141 RADEON_WAIT_UNTIL_2D_IDLE();
1143 OUT_RING(CP_PACKET0(RADEON_PP_CNTL
, 1));
1144 OUT_RING(0x00000000);
1145 OUT_RING(rb3d_cntl
);
1147 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL
, tempRB3D_ZSTENCILCNTL
);
1148 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK
, rb3d_stencilrefmask
);
1149 OUT_RING_REG(RADEON_RB3D_PLANEMASK
, 0x00000000);
1150 OUT_RING_REG(RADEON_SE_CNTL
, depth_clear
->se_cntl
);
1153 /* Make sure we restore the 3D state next time.
1155 dev_priv
->sarea_priv
->ctx_owner
= 0;
1157 for (i
= 0; i
< nbox
; i
++) {
1159 /* Funny that this should be required --
1162 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1166 OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD
, 13));
1167 OUT_RING(RADEON_VTX_Z_PRESENT
|
1168 RADEON_VTX_PKCOLOR_PRESENT
);
1169 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST
|
1170 RADEON_PRIM_WALK_RING
|
1171 RADEON_MAOS_ENABLE
|
1172 RADEON_VTX_FMT_RADEON_MODE
|
1173 (3 << RADEON_NUM_VERTICES_SHIFT
)));
1175 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1176 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y1
]);
1177 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1180 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X1
]);
1181 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1182 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1185 OUT_RING(depth_boxes
[i
].ui
[CLEAR_X2
]);
1186 OUT_RING(depth_boxes
[i
].ui
[CLEAR_Y2
]);
1187 OUT_RING(depth_boxes
[i
].ui
[CLEAR_DEPTH
]);
1194 /* Increment the clear counter. The client-side 3D driver must
1195 * wait on this value before performing the clear ioctl. We
1196 * need this because the card's so damned fast...
1198 dev_priv
->sarea_priv
->last_clear
++;
1202 RADEON_CLEAR_AGE(dev_priv
->sarea_priv
->last_clear
);
1203 RADEON_WAIT_UNTIL_IDLE();
1208 static void radeon_cp_dispatch_swap(drm_device_t
* dev
)
1210 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1211 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1212 int nbox
= sarea_priv
->nbox
;
1213 drm_clip_rect_t
*pbox
= sarea_priv
->boxes
;
1218 /* Do some trivial performance monitoring...
1220 if (dev_priv
->do_boxes
)
1221 radeon_cp_performance_boxes(dev_priv
);
1223 /* Wait for the 3D stream to idle before dispatching the bitblt.
1224 * This will prevent data corruption between the two streams.
1228 RADEON_WAIT_UNTIL_3D_IDLE();
1232 for (i
= 0; i
< nbox
; i
++) {
1235 int w
= pbox
[i
].x2
- x
;
1236 int h
= pbox
[i
].y2
- y
;
1238 DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x
, y
, w
, h
);
1242 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI
, 5));
1243 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
1244 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1245 RADEON_GMC_BRUSH_NONE
|
1246 (dev_priv
->color_fmt
<< 8) |
1247 RADEON_GMC_SRC_DATATYPE_COLOR
|
1249 RADEON_DP_SRC_SOURCE_MEMORY
|
1250 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
1252 /* Make this work even if front & back are flipped:
1254 if (dev_priv
->current_page
== 0) {
1255 OUT_RING(dev_priv
->back_pitch_offset
);
1256 OUT_RING(dev_priv
->front_pitch_offset
);
1258 OUT_RING(dev_priv
->front_pitch_offset
);
1259 OUT_RING(dev_priv
->back_pitch_offset
);
1262 OUT_RING((x
<< 16) | y
);
1263 OUT_RING((x
<< 16) | y
);
1264 OUT_RING((w
<< 16) | h
);
1269 /* Increment the frame counter. The client-side 3D driver must
1270 * throttle the framerate by waiting for this value before
1271 * performing the swapbuffer ioctl.
1273 dev_priv
->sarea_priv
->last_frame
++;
1277 RADEON_FRAME_AGE(dev_priv
->sarea_priv
->last_frame
);
1278 RADEON_WAIT_UNTIL_2D_IDLE();
1283 static void radeon_cp_dispatch_flip(drm_device_t
* dev
)
1285 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1286 drm_sarea_t
*sarea
= (drm_sarea_t
*) dev_priv
->sarea
->handle
;
1287 int offset
= (dev_priv
->current_page
== 1)
1288 ? dev_priv
->front_offset
: dev_priv
->back_offset
;
1290 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
1292 dev_priv
->current_page
, dev_priv
->sarea_priv
->pfCurrentPage
);
1294 /* Do some trivial performance monitoring...
1296 if (dev_priv
->do_boxes
) {
1297 dev_priv
->stats
.boxes
|= RADEON_BOX_FLIP
;
1298 radeon_cp_performance_boxes(dev_priv
);
1301 /* Update the frame offsets for both CRTCs
1305 RADEON_WAIT_UNTIL_3D_IDLE();
1306 OUT_RING_REG(RADEON_CRTC_OFFSET
,
1307 ((sarea
->frame
.y
* dev_priv
->front_pitch
+
1308 sarea
->frame
.x
* (dev_priv
->color_fmt
- 2)) & ~7)
1310 OUT_RING_REG(RADEON_CRTC2_OFFSET
, dev_priv
->sarea_priv
->crtc2_base
1315 /* Increment the frame counter. The client-side 3D driver must
1316 * throttle the framerate by waiting for this value before
1317 * performing the swapbuffer ioctl.
1319 dev_priv
->sarea_priv
->last_frame
++;
1320 dev_priv
->sarea_priv
->pfCurrentPage
= dev_priv
->current_page
=
1321 1 - dev_priv
->current_page
;
1325 RADEON_FRAME_AGE(dev_priv
->sarea_priv
->last_frame
);
1330 static int bad_prim_vertex_nr(int primitive
, int nr
)
1332 switch (primitive
& RADEON_PRIM_TYPE_MASK
) {
1333 case RADEON_PRIM_TYPE_NONE
:
1334 case RADEON_PRIM_TYPE_POINT
:
1336 case RADEON_PRIM_TYPE_LINE
:
1337 return (nr
& 1) || nr
== 0;
1338 case RADEON_PRIM_TYPE_LINE_STRIP
:
1340 case RADEON_PRIM_TYPE_TRI_LIST
:
1341 case RADEON_PRIM_TYPE_3VRT_POINT_LIST
:
1342 case RADEON_PRIM_TYPE_3VRT_LINE_LIST
:
1343 case RADEON_PRIM_TYPE_RECT_LIST
:
1344 return nr
% 3 || nr
== 0;
1345 case RADEON_PRIM_TYPE_TRI_FAN
:
1346 case RADEON_PRIM_TYPE_TRI_STRIP
:
1355 unsigned int finish
;
1357 unsigned int numverts
;
1358 unsigned int offset
;
1359 unsigned int vc_format
;
1360 } drm_radeon_tcl_prim_t
;
1362 static void radeon_cp_dispatch_vertex(drm_device_t
* dev
,
1364 drm_radeon_tcl_prim_t
* prim
)
1366 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1367 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1368 int offset
= dev_priv
->gart_buffers_offset
+ buf
->offset
+ prim
->start
;
1369 int numverts
= (int)prim
->numverts
;
1370 int nbox
= sarea_priv
->nbox
;
1374 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1376 prim
->vc_format
, prim
->start
, prim
->finish
, prim
->numverts
);
1378 if (bad_prim_vertex_nr(prim
->prim
, prim
->numverts
)) {
1379 DRM_ERROR("bad prim %x numverts %d\n",
1380 prim
->prim
, prim
->numverts
);
1385 /* Emit the next cliprect */
1387 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1390 /* Emit the vertex buffer rendering commands */
1393 OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM
, 3));
1396 OUT_RING(prim
->vc_format
);
1397 OUT_RING(prim
->prim
| RADEON_PRIM_WALK_LIST
|
1398 RADEON_COLOR_ORDER_RGBA
|
1399 RADEON_VTX_FMT_RADEON_MODE
|
1400 (numverts
<< RADEON_NUM_VERTICES_SHIFT
));
1408 static void radeon_cp_discard_buffer(drm_device_t
* dev
, drm_buf_t
* buf
)
1410 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1411 drm_radeon_buf_priv_t
*buf_priv
= buf
->dev_private
;
1414 buf_priv
->age
= ++dev_priv
->sarea_priv
->last_dispatch
;
1416 /* Emit the vertex buffer age */
1418 RADEON_DISPATCH_AGE(buf_priv
->age
);
1425 static void radeon_cp_dispatch_indirect(drm_device_t
* dev
,
1426 drm_buf_t
* buf
, int start
, int end
)
1428 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1430 DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf
->idx
, start
, end
);
1433 int offset
= (dev_priv
->gart_buffers_offset
1434 + buf
->offset
+ start
);
1435 int dwords
= (end
- start
+ 3) / sizeof(u32
);
1437 /* Indirect buffer data must be an even number of
1438 * dwords, so if we've been given an odd number we must
1439 * pad the data with a Type-2 CP packet.
1443 ((char *)dev
->agp_buffer_map
->handle
1444 + buf
->offset
+ start
);
1445 data
[dwords
++] = RADEON_CP_PACKET2
;
1448 /* Fire off the indirect buffer */
1451 OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE
, 1));
1459 static void radeon_cp_dispatch_indices(drm_device_t
* dev
,
1460 drm_buf_t
* elt_buf
,
1461 drm_radeon_tcl_prim_t
* prim
)
1463 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1464 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
1465 int offset
= dev_priv
->gart_buffers_offset
+ prim
->offset
;
1469 int start
= prim
->start
+ RADEON_INDEX_PRIM_OFFSET
;
1470 int count
= (prim
->finish
- start
) / sizeof(u16
);
1471 int nbox
= sarea_priv
->nbox
;
1473 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1476 prim
->start
, prim
->finish
, prim
->offset
, prim
->numverts
);
1478 if (bad_prim_vertex_nr(prim
->prim
, count
)) {
1479 DRM_ERROR("bad prim %x count %d\n", prim
->prim
, count
);
1483 if (start
>= prim
->finish
|| (prim
->start
& 0x7)) {
1484 DRM_ERROR("buffer prim %d\n", prim
->prim
);
1488 dwords
= (prim
->finish
- prim
->start
+ 3) / sizeof(u32
);
1490 data
= (u32
*) ((char *)dev
->agp_buffer_map
->handle
+
1491 elt_buf
->offset
+ prim
->start
);
1493 data
[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM
, dwords
- 2);
1495 data
[2] = prim
->numverts
;
1496 data
[3] = prim
->vc_format
;
1497 data
[4] = (prim
->prim
|
1498 RADEON_PRIM_WALK_IND
|
1499 RADEON_COLOR_ORDER_RGBA
|
1500 RADEON_VTX_FMT_RADEON_MODE
|
1501 (count
<< RADEON_NUM_VERTICES_SHIFT
));
1505 radeon_emit_clip_rect(dev_priv
, &sarea_priv
->boxes
[i
]);
1507 radeon_cp_dispatch_indirect(dev
, elt_buf
,
1508 prim
->start
, prim
->finish
);
1515 #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1517 static int radeon_cp_dispatch_texture(DRMFILE filp
,
1519 drm_radeon_texture_t
* tex
,
1520 drm_radeon_tex_image_t
* image
)
1522 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1523 drm_file_t
*filp_priv
;
1527 const u8 __user
*data
;
1528 int size
, dwords
, tex_width
, blit_width
, spitch
;
1531 u32 texpitch
, microtile
;
1535 DRM_GET_PRIV_WITH_RETURN(filp_priv
, filp
);
1537 if (radeon_check_and_fixup_offset(dev_priv
, filp_priv
, &tex
->offset
)) {
1538 DRM_ERROR("Invalid destination offset\n");
1539 return DRM_ERR(EINVAL
);
1542 dev_priv
->stats
.boxes
|= RADEON_BOX_TEXTURE_LOAD
;
1544 /* Flush the pixel cache. This ensures no pixel data gets mixed
1545 * up with the texture data from the host data blit, otherwise
1546 * part of the texture image may be corrupted.
1549 RADEON_FLUSH_CACHE();
1550 RADEON_WAIT_UNTIL_IDLE();
1553 /* The compiler won't optimize away a division by a variable,
1554 * even if the only legal values are powers of two. Thus, we'll
1555 * use a shift instead.
1557 switch (tex
->format
) {
1558 case RADEON_TXFORMAT_ARGB8888
:
1559 case RADEON_TXFORMAT_RGBA8888
:
1560 format
= RADEON_COLOR_FORMAT_ARGB8888
;
1561 tex_width
= tex
->width
* 4;
1562 blit_width
= image
->width
* 4;
1564 case RADEON_TXFORMAT_AI88
:
1565 case RADEON_TXFORMAT_ARGB1555
:
1566 case RADEON_TXFORMAT_RGB565
:
1567 case RADEON_TXFORMAT_ARGB4444
:
1568 case RADEON_TXFORMAT_VYUY422
:
1569 case RADEON_TXFORMAT_YVYU422
:
1570 format
= RADEON_COLOR_FORMAT_RGB565
;
1571 tex_width
= tex
->width
* 2;
1572 blit_width
= image
->width
* 2;
1574 case RADEON_TXFORMAT_I8
:
1575 case RADEON_TXFORMAT_RGB332
:
1576 format
= RADEON_COLOR_FORMAT_CI8
;
1577 tex_width
= tex
->width
* 1;
1578 blit_width
= image
->width
* 1;
1581 DRM_ERROR("invalid texture format %d\n", tex
->format
);
1582 return DRM_ERR(EINVAL
);
1584 spitch
= blit_width
>> 6;
1585 if (spitch
== 0 && image
->height
> 1)
1586 return DRM_ERR(EINVAL
);
1588 texpitch
= tex
->pitch
;
1589 if ((texpitch
<< 22) & RADEON_DST_TILE_MICRO
) {
1591 if (tex_width
< 64) {
1592 texpitch
&= ~(RADEON_DST_TILE_MICRO
>> 22);
1593 /* we got tiled coordinates, untile them */
1599 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width
, tex
->height
, blit_width
);
1602 DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1603 tex
->offset
>> 10, tex
->pitch
, tex
->format
,
1604 image
->x
, image
->y
, image
->width
, image
->height
);
1606 /* Make a copy of some parameters in case we have to
1607 * update them for a multi-pass texture blit.
1609 height
= image
->height
;
1610 data
= (const u8 __user
*)image
->data
;
1612 size
= height
* blit_width
;
1614 if (size
> RADEON_MAX_TEXTURE_SIZE
) {
1615 height
= RADEON_MAX_TEXTURE_SIZE
/ blit_width
;
1616 size
= height
* blit_width
;
1617 } else if (size
< 4 && size
> 0) {
1619 } else if (size
== 0) {
1623 buf
= radeon_freelist_get(dev
);
1625 radeon_do_cp_idle(dev_priv
);
1626 buf
= radeon_freelist_get(dev
);
1629 DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
1630 if (DRM_COPY_TO_USER(tex
->image
, image
, sizeof(*image
)))
1631 return DRM_ERR(EFAULT
);
1632 return DRM_ERR(EAGAIN
);
1635 /* Dispatch the indirect buffer.
1638 (u32
*) ((char *)dev
->agp_buffer_map
->handle
+ buf
->offset
);
1642 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
1643 however, we cannot use blitter directly for texture width < 64 bytes,
1644 since minimum tex pitch is 64 bytes and we need this to match
1645 the texture width, otherwise the blitter will tile it wrong.
1646 Thus, tiling manually in this case. Additionally, need to special
1647 case tex height = 1, since our actual image will have height 2
1648 and we need to ensure we don't read beyond the texture size
1650 if (tex
->height
== 1) {
1651 if (tex_width
>= 64 || tex_width
<= 16) {
1652 if (DRM_COPY_FROM_USER(buffer
, data
,
1656 ("EFAULT on pad, %d bytes\n",
1658 return DRM_ERR(EFAULT
);
1660 } else if (tex_width
== 32) {
1661 if (DRM_COPY_FROM_USER
1662 (buffer
, data
, 16)) {
1664 ("EFAULT on pad, %d bytes\n",
1666 return DRM_ERR(EFAULT
);
1668 if (DRM_COPY_FROM_USER
1669 (buffer
+ 8, data
+ 16, 16)) {
1671 ("EFAULT on pad, %d bytes\n",
1673 return DRM_ERR(EFAULT
);
1676 } else if (tex_width
>= 64 || tex_width
== 16) {
1677 if (DRM_COPY_FROM_USER(buffer
, data
,
1678 dwords
* sizeof(u32
))) {
1679 DRM_ERROR("EFAULT on data, %d dwords\n",
1681 return DRM_ERR(EFAULT
);
1683 } else if (tex_width
< 16) {
1684 for (i
= 0; i
< tex
->height
; i
++) {
1685 if (DRM_COPY_FROM_USER
1686 (buffer
, data
, tex_width
)) {
1688 ("EFAULT on pad, %d bytes\n",
1690 return DRM_ERR(EFAULT
);
1695 } else if (tex_width
== 32) {
1696 /* TODO: make sure this works when not fitting in one buffer
1697 (i.e. 32bytes x 2048...) */
1698 for (i
= 0; i
< tex
->height
; i
+= 2) {
1699 if (DRM_COPY_FROM_USER
1700 (buffer
, data
, 16)) {
1702 ("EFAULT on pad, %d bytes\n",
1704 return DRM_ERR(EFAULT
);
1707 if (DRM_COPY_FROM_USER
1708 (buffer
+ 8, data
, 16)) {
1710 ("EFAULT on pad, %d bytes\n",
1712 return DRM_ERR(EFAULT
);
1715 if (DRM_COPY_FROM_USER
1716 (buffer
+ 4, data
, 16)) {
1718 ("EFAULT on pad, %d bytes\n",
1720 return DRM_ERR(EFAULT
);
1723 if (DRM_COPY_FROM_USER
1724 (buffer
+ 12, data
, 16)) {
1726 ("EFAULT on pad, %d bytes\n",
1728 return DRM_ERR(EFAULT
);
1735 if (tex_width
>= 32) {
1736 /* Texture image width is larger than the minimum, so we
1737 * can upload it directly.
1739 if (DRM_COPY_FROM_USER(buffer
, data
,
1740 dwords
* sizeof(u32
))) {
1741 DRM_ERROR("EFAULT on data, %d dwords\n",
1743 return DRM_ERR(EFAULT
);
1746 /* Texture image width is less than the minimum, so we
1747 * need to pad out each image scanline to the minimum
1750 for (i
= 0; i
< tex
->height
; i
++) {
1751 if (DRM_COPY_FROM_USER
1752 (buffer
, data
, tex_width
)) {
1754 ("EFAULT on pad, %d bytes\n",
1756 return DRM_ERR(EFAULT
);
1766 offset
= dev_priv
->gart_buffers_offset
+ buf
->offset
;
1768 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI
, 5));
1769 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
1770 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
1771 RADEON_GMC_BRUSH_NONE
|
1773 RADEON_GMC_SRC_DATATYPE_COLOR
|
1775 RADEON_DP_SRC_SOURCE_MEMORY
|
1776 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
1777 OUT_RING((spitch
<< 22) | (offset
>> 10));
1778 OUT_RING((texpitch
<< 22) | (tex
->offset
>> 10));
1780 OUT_RING((image
->x
<< 16) | image
->y
);
1781 OUT_RING((image
->width
<< 16) | height
);
1782 RADEON_WAIT_UNTIL_2D_IDLE();
1785 radeon_cp_discard_buffer(dev
, buf
);
1787 /* Update the input parameters for next time */
1789 image
->height
-= height
;
1790 image
->data
= (const u8 __user
*)image
->data
+ size
;
1791 } while (image
->height
> 0);
1793 /* Flush the pixel cache after the blit completes. This ensures
1794 * the texture data is written out to memory before rendering
1798 RADEON_FLUSH_CACHE();
1799 RADEON_WAIT_UNTIL_2D_IDLE();
1804 static void radeon_cp_dispatch_stipple(drm_device_t
* dev
, u32
* stipple
)
1806 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1813 OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR
, 0));
1814 OUT_RING(0x00000000);
1816 OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA
, 31));
1817 for (i
= 0; i
< 32; i
++) {
1818 OUT_RING(stipple
[i
]);
1824 static void radeon_apply_surface_regs(int surf_index
,
1825 drm_radeon_private_t
* dev_priv
)
1827 if (!dev_priv
->mmio
)
1830 radeon_do_cp_idle(dev_priv
);
1832 RADEON_WRITE(RADEON_SURFACE0_INFO
+ 16 * surf_index
,
1833 dev_priv
->surfaces
[surf_index
].flags
);
1834 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND
+ 16 * surf_index
,
1835 dev_priv
->surfaces
[surf_index
].lower
);
1836 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND
+ 16 * surf_index
,
1837 dev_priv
->surfaces
[surf_index
].upper
);
1840 /* Allocates a virtual surface
1841 * doesn't always allocate a real surface, will stretch an existing
1842 * surface when possible.
1844 * Note that refcount can be at most 2, since during a free refcount=3
1845 * might mean we have to allocate a new surface which might not always
1847 * For example : we allocate three contigous surfaces ABC. If B is
1848 * freed, we suddenly need two surfaces to store A and C, which might
1849 * not always be available.
1851 static int alloc_surface(drm_radeon_surface_alloc_t
* new,
1852 drm_radeon_private_t
* dev_priv
, DRMFILE filp
)
1854 struct radeon_virt_surface
*s
;
1856 int virt_surface_index
;
1857 uint32_t new_upper
, new_lower
;
1859 new_lower
= new->address
;
1860 new_upper
= new_lower
+ new->size
- 1;
1863 if ((new_lower
>= new_upper
) || (new->flags
== 0) || (new->size
== 0) ||
1864 ((new_upper
& RADEON_SURF_ADDRESS_FIXED_MASK
) !=
1865 RADEON_SURF_ADDRESS_FIXED_MASK
)
1866 || ((new_lower
& RADEON_SURF_ADDRESS_FIXED_MASK
) != 0))
1869 /* make sure there is no overlap with existing surfaces */
1870 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
1871 if ((dev_priv
->surfaces
[i
].refcount
!= 0) &&
1872 (((new_lower
>= dev_priv
->surfaces
[i
].lower
) &&
1873 (new_lower
< dev_priv
->surfaces
[i
].upper
)) ||
1874 ((new_lower
< dev_priv
->surfaces
[i
].lower
) &&
1875 (new_upper
> dev_priv
->surfaces
[i
].lower
)))) {
1880 /* find a virtual surface */
1881 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++)
1882 if (dev_priv
->virt_surfaces
[i
].filp
== 0)
1884 if (i
== 2 * RADEON_MAX_SURFACES
) {
1887 virt_surface_index
= i
;
1889 /* try to reuse an existing surface */
1890 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
1892 if ((dev_priv
->surfaces
[i
].refcount
== 1) &&
1893 (new->flags
== dev_priv
->surfaces
[i
].flags
) &&
1894 (new_upper
+ 1 == dev_priv
->surfaces
[i
].lower
)) {
1895 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
1896 s
->surface_index
= i
;
1897 s
->lower
= new_lower
;
1898 s
->upper
= new_upper
;
1899 s
->flags
= new->flags
;
1901 dev_priv
->surfaces
[i
].refcount
++;
1902 dev_priv
->surfaces
[i
].lower
= s
->lower
;
1903 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
1904 return virt_surface_index
;
1908 if ((dev_priv
->surfaces
[i
].refcount
== 1) &&
1909 (new->flags
== dev_priv
->surfaces
[i
].flags
) &&
1910 (new_lower
== dev_priv
->surfaces
[i
].upper
+ 1)) {
1911 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
1912 s
->surface_index
= i
;
1913 s
->lower
= new_lower
;
1914 s
->upper
= new_upper
;
1915 s
->flags
= new->flags
;
1917 dev_priv
->surfaces
[i
].refcount
++;
1918 dev_priv
->surfaces
[i
].upper
= s
->upper
;
1919 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
1920 return virt_surface_index
;
1924 /* okay, we need a new one */
1925 for (i
= 0; i
< RADEON_MAX_SURFACES
; i
++) {
1926 if (dev_priv
->surfaces
[i
].refcount
== 0) {
1927 s
= &(dev_priv
->virt_surfaces
[virt_surface_index
]);
1928 s
->surface_index
= i
;
1929 s
->lower
= new_lower
;
1930 s
->upper
= new_upper
;
1931 s
->flags
= new->flags
;
1933 dev_priv
->surfaces
[i
].refcount
= 1;
1934 dev_priv
->surfaces
[i
].lower
= s
->lower
;
1935 dev_priv
->surfaces
[i
].upper
= s
->upper
;
1936 dev_priv
->surfaces
[i
].flags
= s
->flags
;
1937 radeon_apply_surface_regs(s
->surface_index
, dev_priv
);
1938 return virt_surface_index
;
1942 /* we didn't find anything */
1946 static int free_surface(DRMFILE filp
, drm_radeon_private_t
* dev_priv
,
1949 struct radeon_virt_surface
*s
;
1951 /* find the virtual surface */
1952 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++) {
1953 s
= &(dev_priv
->virt_surfaces
[i
]);
1955 if ((lower
== s
->lower
) && (filp
== s
->filp
)) {
1956 if (dev_priv
->surfaces
[s
->surface_index
].
1958 dev_priv
->surfaces
[s
->surface_index
].
1961 if (dev_priv
->surfaces
[s
->surface_index
].
1963 dev_priv
->surfaces
[s
->surface_index
].
1966 dev_priv
->surfaces
[s
->surface_index
].refcount
--;
1967 if (dev_priv
->surfaces
[s
->surface_index
].
1969 dev_priv
->surfaces
[s
->surface_index
].
1972 radeon_apply_surface_regs(s
->surface_index
,
1981 static void radeon_surfaces_release(DRMFILE filp
,
1982 drm_radeon_private_t
* dev_priv
)
1985 for (i
= 0; i
< 2 * RADEON_MAX_SURFACES
; i
++) {
1986 if (dev_priv
->virt_surfaces
[i
].filp
== filp
)
1987 free_surface(filp
, dev_priv
,
1988 dev_priv
->virt_surfaces
[i
].lower
);
1992 /* ================================================================
1995 static int radeon_surface_alloc(DRM_IOCTL_ARGS
)
1998 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
1999 drm_radeon_surface_alloc_t alloc
;
2002 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2003 return DRM_ERR(EINVAL
);
2006 DRM_COPY_FROM_USER_IOCTL(alloc
,
2007 (drm_radeon_surface_alloc_t __user
*) data
,
2010 if (alloc_surface(&alloc
, dev_priv
, filp
) == -1)
2011 return DRM_ERR(EINVAL
);
2016 static int radeon_surface_free(DRM_IOCTL_ARGS
)
2019 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2020 drm_radeon_surface_free_t memfree
;
2023 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2024 return DRM_ERR(EINVAL
);
2027 DRM_COPY_FROM_USER_IOCTL(memfree
, (drm_radeon_mem_free_t __user
*) data
,
2030 if (free_surface(filp
, dev_priv
, memfree
.address
))
2031 return DRM_ERR(EINVAL
);
2036 static int radeon_cp_clear(DRM_IOCTL_ARGS
)
2039 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2040 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2041 drm_radeon_clear_t clear
;
2042 drm_radeon_clear_rect_t depth_boxes
[RADEON_NR_SAREA_CLIPRECTS
];
2045 LOCK_TEST_WITH_RETURN(dev
, filp
);
2047 DRM_COPY_FROM_USER_IOCTL(clear
, (drm_radeon_clear_t __user
*) data
,
2050 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2052 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2053 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
2055 if (DRM_COPY_FROM_USER(&depth_boxes
, clear
.depth_boxes
,
2056 sarea_priv
->nbox
* sizeof(depth_boxes
[0])))
2057 return DRM_ERR(EFAULT
);
2059 radeon_cp_dispatch_clear(dev
, &clear
, depth_boxes
);
2065 /* Not sure why this isn't set all the time:
2067 static int radeon_do_init_pageflip(drm_device_t
* dev
)
2069 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2075 RADEON_WAIT_UNTIL_3D_IDLE();
2076 OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL
, 0));
2077 OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL
) |
2078 RADEON_CRTC_OFFSET_FLIP_CNTL
);
2079 OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL
, 0));
2080 OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL
) |
2081 RADEON_CRTC_OFFSET_FLIP_CNTL
);
2084 dev_priv
->page_flipping
= 1;
2085 dev_priv
->current_page
= 0;
2086 dev_priv
->sarea_priv
->pfCurrentPage
= dev_priv
->current_page
;
2091 /* Called whenever a client dies, from drm_release.
2092 * NOTE: Lock isn't necessarily held when this is called!
2094 static int radeon_do_cleanup_pageflip(drm_device_t
* dev
)
2096 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2099 if (dev_priv
->current_page
!= 0)
2100 radeon_cp_dispatch_flip(dev
);
2102 dev_priv
->page_flipping
= 0;
2106 /* Swapping and flipping are different operations, need different ioctls.
2107 * They can & should be intermixed to support multiple 3d windows.
2109 static int radeon_cp_flip(DRM_IOCTL_ARGS
)
2112 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2115 LOCK_TEST_WITH_RETURN(dev
, filp
);
2117 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2119 if (!dev_priv
->page_flipping
)
2120 radeon_do_init_pageflip(dev
);
2122 radeon_cp_dispatch_flip(dev
);
2128 static int radeon_cp_swap(DRM_IOCTL_ARGS
)
2131 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2132 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2135 LOCK_TEST_WITH_RETURN(dev
, filp
);
2137 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2139 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2140 sarea_priv
->nbox
= RADEON_NR_SAREA_CLIPRECTS
;
2142 radeon_cp_dispatch_swap(dev
);
2143 dev_priv
->sarea_priv
->ctx_owner
= 0;
2149 static int radeon_cp_vertex(DRM_IOCTL_ARGS
)
2152 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2153 drm_file_t
*filp_priv
;
2154 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2155 drm_device_dma_t
*dma
= dev
->dma
;
2157 drm_radeon_vertex_t vertex
;
2158 drm_radeon_tcl_prim_t prim
;
2160 LOCK_TEST_WITH_RETURN(dev
, filp
);
2162 DRM_GET_PRIV_WITH_RETURN(filp_priv
, filp
);
2164 DRM_COPY_FROM_USER_IOCTL(vertex
, (drm_radeon_vertex_t __user
*) data
,
2167 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2168 DRM_CURRENTPID
, vertex
.idx
, vertex
.count
, vertex
.discard
);
2170 if (vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
2171 DRM_ERROR("buffer index %d (of %d max)\n",
2172 vertex
.idx
, dma
->buf_count
- 1);
2173 return DRM_ERR(EINVAL
);
2175 if (vertex
.prim
< 0 || vertex
.prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
2176 DRM_ERROR("buffer prim %d\n", vertex
.prim
);
2177 return DRM_ERR(EINVAL
);
2180 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2181 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2183 buf
= dma
->buflist
[vertex
.idx
];
2185 if (buf
->filp
!= filp
) {
2186 DRM_ERROR("process %d using buffer owned by %p\n",
2187 DRM_CURRENTPID
, buf
->filp
);
2188 return DRM_ERR(EINVAL
);
2191 DRM_ERROR("sending pending buffer %d\n", vertex
.idx
);
2192 return DRM_ERR(EINVAL
);
2195 /* Build up a prim_t record:
2198 buf
->used
= vertex
.count
; /* not used? */
2200 if (sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
2201 if (radeon_emit_state(dev_priv
, filp_priv
,
2202 &sarea_priv
->context_state
,
2203 sarea_priv
->tex_state
,
2204 sarea_priv
->dirty
)) {
2205 DRM_ERROR("radeon_emit_state failed\n");
2206 return DRM_ERR(EINVAL
);
2209 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
2210 RADEON_UPLOAD_TEX1IMAGES
|
2211 RADEON_UPLOAD_TEX2IMAGES
|
2212 RADEON_REQUIRE_QUIESCENCE
);
2216 prim
.finish
= vertex
.count
; /* unused */
2217 prim
.prim
= vertex
.prim
;
2218 prim
.numverts
= vertex
.count
;
2219 prim
.vc_format
= dev_priv
->sarea_priv
->vc_format
;
2221 radeon_cp_dispatch_vertex(dev
, buf
, &prim
);
2224 if (vertex
.discard
) {
2225 radeon_cp_discard_buffer(dev
, buf
);
2232 static int radeon_cp_indices(DRM_IOCTL_ARGS
)
2235 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2236 drm_file_t
*filp_priv
;
2237 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2238 drm_device_dma_t
*dma
= dev
->dma
;
2240 drm_radeon_indices_t elts
;
2241 drm_radeon_tcl_prim_t prim
;
2244 LOCK_TEST_WITH_RETURN(dev
, filp
);
2247 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2248 return DRM_ERR(EINVAL
);
2251 DRM_GET_PRIV_WITH_RETURN(filp_priv
, filp
);
2253 DRM_COPY_FROM_USER_IOCTL(elts
, (drm_radeon_indices_t __user
*) data
,
2256 DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2257 DRM_CURRENTPID
, elts
.idx
, elts
.start
, elts
.end
, elts
.discard
);
2259 if (elts
.idx
< 0 || elts
.idx
>= dma
->buf_count
) {
2260 DRM_ERROR("buffer index %d (of %d max)\n",
2261 elts
.idx
, dma
->buf_count
- 1);
2262 return DRM_ERR(EINVAL
);
2264 if (elts
.prim
< 0 || elts
.prim
> RADEON_PRIM_TYPE_3VRT_LINE_LIST
) {
2265 DRM_ERROR("buffer prim %d\n", elts
.prim
);
2266 return DRM_ERR(EINVAL
);
2269 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2270 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2272 buf
= dma
->buflist
[elts
.idx
];
2274 if (buf
->filp
!= filp
) {
2275 DRM_ERROR("process %d using buffer owned by %p\n",
2276 DRM_CURRENTPID
, buf
->filp
);
2277 return DRM_ERR(EINVAL
);
2280 DRM_ERROR("sending pending buffer %d\n", elts
.idx
);
2281 return DRM_ERR(EINVAL
);
2284 count
= (elts
.end
- elts
.start
) / sizeof(u16
);
2285 elts
.start
-= RADEON_INDEX_PRIM_OFFSET
;
2287 if (elts
.start
& 0x7) {
2288 DRM_ERROR("misaligned buffer 0x%x\n", elts
.start
);
2289 return DRM_ERR(EINVAL
);
2291 if (elts
.start
< buf
->used
) {
2292 DRM_ERROR("no header 0x%x - 0x%x\n", elts
.start
, buf
->used
);
2293 return DRM_ERR(EINVAL
);
2296 buf
->used
= elts
.end
;
2298 if (sarea_priv
->dirty
& ~RADEON_UPLOAD_CLIPRECTS
) {
2299 if (radeon_emit_state(dev_priv
, filp_priv
,
2300 &sarea_priv
->context_state
,
2301 sarea_priv
->tex_state
,
2302 sarea_priv
->dirty
)) {
2303 DRM_ERROR("radeon_emit_state failed\n");
2304 return DRM_ERR(EINVAL
);
2307 sarea_priv
->dirty
&= ~(RADEON_UPLOAD_TEX0IMAGES
|
2308 RADEON_UPLOAD_TEX1IMAGES
|
2309 RADEON_UPLOAD_TEX2IMAGES
|
2310 RADEON_REQUIRE_QUIESCENCE
);
2313 /* Build up a prim_t record:
2315 prim
.start
= elts
.start
;
2316 prim
.finish
= elts
.end
;
2317 prim
.prim
= elts
.prim
;
2318 prim
.offset
= 0; /* offset from start of dma buffers */
2319 prim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
2320 prim
.vc_format
= dev_priv
->sarea_priv
->vc_format
;
2322 radeon_cp_dispatch_indices(dev
, buf
, &prim
);
2324 radeon_cp_discard_buffer(dev
, buf
);
2331 static int radeon_cp_texture(DRM_IOCTL_ARGS
)
2334 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2335 drm_radeon_texture_t tex
;
2336 drm_radeon_tex_image_t image
;
2339 LOCK_TEST_WITH_RETURN(dev
, filp
);
2341 DRM_COPY_FROM_USER_IOCTL(tex
, (drm_radeon_texture_t __user
*) data
,
2344 if (tex
.image
== NULL
) {
2345 DRM_ERROR("null texture image!\n");
2346 return DRM_ERR(EINVAL
);
2349 if (DRM_COPY_FROM_USER(&image
,
2350 (drm_radeon_tex_image_t __user
*) tex
.image
,
2352 return DRM_ERR(EFAULT
);
2354 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2355 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2357 ret
= radeon_cp_dispatch_texture(filp
, dev
, &tex
, &image
);
2363 static int radeon_cp_stipple(DRM_IOCTL_ARGS
)
2366 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2367 drm_radeon_stipple_t stipple
;
2370 LOCK_TEST_WITH_RETURN(dev
, filp
);
2372 DRM_COPY_FROM_USER_IOCTL(stipple
, (drm_radeon_stipple_t __user
*) data
,
2375 if (DRM_COPY_FROM_USER(&mask
, stipple
.mask
, 32 * sizeof(u32
)))
2376 return DRM_ERR(EFAULT
);
2378 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2380 radeon_cp_dispatch_stipple(dev
, mask
);
2386 static int radeon_cp_indirect(DRM_IOCTL_ARGS
)
2389 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2390 drm_device_dma_t
*dma
= dev
->dma
;
2392 drm_radeon_indirect_t indirect
;
2395 LOCK_TEST_WITH_RETURN(dev
, filp
);
2398 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2399 return DRM_ERR(EINVAL
);
2402 DRM_COPY_FROM_USER_IOCTL(indirect
,
2403 (drm_radeon_indirect_t __user
*) data
,
2406 DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
2407 indirect
.idx
, indirect
.start
, indirect
.end
, indirect
.discard
);
2409 if (indirect
.idx
< 0 || indirect
.idx
>= dma
->buf_count
) {
2410 DRM_ERROR("buffer index %d (of %d max)\n",
2411 indirect
.idx
, dma
->buf_count
- 1);
2412 return DRM_ERR(EINVAL
);
2415 buf
= dma
->buflist
[indirect
.idx
];
2417 if (buf
->filp
!= filp
) {
2418 DRM_ERROR("process %d using buffer owned by %p\n",
2419 DRM_CURRENTPID
, buf
->filp
);
2420 return DRM_ERR(EINVAL
);
2423 DRM_ERROR("sending pending buffer %d\n", indirect
.idx
);
2424 return DRM_ERR(EINVAL
);
2427 if (indirect
.start
< buf
->used
) {
2428 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2429 indirect
.start
, buf
->used
);
2430 return DRM_ERR(EINVAL
);
2433 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2434 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2436 buf
->used
= indirect
.end
;
2438 /* Wait for the 3D stream to idle before the indirect buffer
2439 * containing 2D acceleration commands is processed.
2443 RADEON_WAIT_UNTIL_3D_IDLE();
2447 /* Dispatch the indirect buffer full of commands from the
2448 * X server. This is insecure and is thus only available to
2449 * privileged clients.
2451 radeon_cp_dispatch_indirect(dev
, buf
, indirect
.start
, indirect
.end
);
2452 if (indirect
.discard
) {
2453 radeon_cp_discard_buffer(dev
, buf
);
2460 static int radeon_cp_vertex2(DRM_IOCTL_ARGS
)
2463 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2464 drm_file_t
*filp_priv
;
2465 drm_radeon_sarea_t
*sarea_priv
= dev_priv
->sarea_priv
;
2466 drm_device_dma_t
*dma
= dev
->dma
;
2468 drm_radeon_vertex2_t vertex
;
2470 unsigned char laststate
;
2472 LOCK_TEST_WITH_RETURN(dev
, filp
);
2475 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2476 return DRM_ERR(EINVAL
);
2479 DRM_GET_PRIV_WITH_RETURN(filp_priv
, filp
);
2481 DRM_COPY_FROM_USER_IOCTL(vertex
, (drm_radeon_vertex2_t __user
*) data
,
2484 DRM_DEBUG("pid=%d index=%d discard=%d\n",
2485 DRM_CURRENTPID
, vertex
.idx
, vertex
.discard
);
2487 if (vertex
.idx
< 0 || vertex
.idx
>= dma
->buf_count
) {
2488 DRM_ERROR("buffer index %d (of %d max)\n",
2489 vertex
.idx
, dma
->buf_count
- 1);
2490 return DRM_ERR(EINVAL
);
2493 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2494 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2496 buf
= dma
->buflist
[vertex
.idx
];
2498 if (buf
->filp
!= filp
) {
2499 DRM_ERROR("process %d using buffer owned by %p\n",
2500 DRM_CURRENTPID
, buf
->filp
);
2501 return DRM_ERR(EINVAL
);
2505 DRM_ERROR("sending pending buffer %d\n", vertex
.idx
);
2506 return DRM_ERR(EINVAL
);
2509 if (sarea_priv
->nbox
> RADEON_NR_SAREA_CLIPRECTS
)
2510 return DRM_ERR(EINVAL
);
2512 for (laststate
= 0xff, i
= 0; i
< vertex
.nr_prims
; i
++) {
2513 drm_radeon_prim_t prim
;
2514 drm_radeon_tcl_prim_t tclprim
;
2516 if (DRM_COPY_FROM_USER(&prim
, &vertex
.prim
[i
], sizeof(prim
)))
2517 return DRM_ERR(EFAULT
);
2519 if (prim
.stateidx
!= laststate
) {
2520 drm_radeon_state_t state
;
2522 if (DRM_COPY_FROM_USER(&state
,
2523 &vertex
.state
[prim
.stateidx
],
2525 return DRM_ERR(EFAULT
);
2527 if (radeon_emit_state2(dev_priv
, filp_priv
, &state
)) {
2528 DRM_ERROR("radeon_emit_state2 failed\n");
2529 return DRM_ERR(EINVAL
);
2532 laststate
= prim
.stateidx
;
2535 tclprim
.start
= prim
.start
;
2536 tclprim
.finish
= prim
.finish
;
2537 tclprim
.prim
= prim
.prim
;
2538 tclprim
.vc_format
= prim
.vc_format
;
2540 if (prim
.prim
& RADEON_PRIM_WALK_IND
) {
2541 tclprim
.offset
= prim
.numverts
* 64;
2542 tclprim
.numverts
= RADEON_MAX_VB_VERTS
; /* duh */
2544 radeon_cp_dispatch_indices(dev
, buf
, &tclprim
);
2546 tclprim
.numverts
= prim
.numverts
;
2547 tclprim
.offset
= 0; /* not used */
2549 radeon_cp_dispatch_vertex(dev
, buf
, &tclprim
);
2552 if (sarea_priv
->nbox
== 1)
2553 sarea_priv
->nbox
= 0;
2556 if (vertex
.discard
) {
2557 radeon_cp_discard_buffer(dev
, buf
);
2564 static int radeon_emit_packets(drm_radeon_private_t
* dev_priv
,
2565 drm_file_t
* filp_priv
,
2566 drm_radeon_cmd_header_t header
,
2567 drm_radeon_cmd_buffer_t
* cmdbuf
)
2569 int id
= (int)header
.packet
.packet_id
;
2571 int *data
= (int *)cmdbuf
->buf
;
2574 if (id
>= RADEON_MAX_STATE_PACKETS
)
2575 return DRM_ERR(EINVAL
);
2577 sz
= packet
[id
].len
;
2578 reg
= packet
[id
].start
;
2580 if (sz
* sizeof(int) > cmdbuf
->bufsz
) {
2581 DRM_ERROR("Packet size provided larger than data provided\n");
2582 return DRM_ERR(EINVAL
);
2585 if (radeon_check_and_fixup_packets(dev_priv
, filp_priv
, id
, data
)) {
2586 DRM_ERROR("Packet verification failed\n");
2587 return DRM_ERR(EINVAL
);
2591 OUT_RING(CP_PACKET0(reg
, (sz
- 1)));
2592 OUT_RING_TABLE(data
, sz
);
2595 cmdbuf
->buf
+= sz
* sizeof(int);
2596 cmdbuf
->bufsz
-= sz
* sizeof(int);
2600 static __inline__
int radeon_emit_scalars(drm_radeon_private_t
* dev_priv
,
2601 drm_radeon_cmd_header_t header
,
2602 drm_radeon_cmd_buffer_t
* cmdbuf
)
2604 int sz
= header
.scalars
.count
;
2605 int start
= header
.scalars
.offset
;
2606 int stride
= header
.scalars
.stride
;
2610 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG
, 0));
2611 OUT_RING(start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
2612 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG
, sz
- 1));
2613 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2615 cmdbuf
->buf
+= sz
* sizeof(int);
2616 cmdbuf
->bufsz
-= sz
* sizeof(int);
2622 static __inline__
int radeon_emit_scalars2(drm_radeon_private_t
* dev_priv
,
2623 drm_radeon_cmd_header_t header
,
2624 drm_radeon_cmd_buffer_t
* cmdbuf
)
2626 int sz
= header
.scalars
.count
;
2627 int start
= ((unsigned int)header
.scalars
.offset
) + 0x100;
2628 int stride
= header
.scalars
.stride
;
2632 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG
, 0));
2633 OUT_RING(start
| (stride
<< RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT
));
2634 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG
, sz
- 1));
2635 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2637 cmdbuf
->buf
+= sz
* sizeof(int);
2638 cmdbuf
->bufsz
-= sz
* sizeof(int);
2642 static __inline__
int radeon_emit_vectors(drm_radeon_private_t
* dev_priv
,
2643 drm_radeon_cmd_header_t header
,
2644 drm_radeon_cmd_buffer_t
* cmdbuf
)
2646 int sz
= header
.vectors
.count
;
2647 int start
= header
.vectors
.offset
;
2648 int stride
= header
.vectors
.stride
;
2652 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG
, 0));
2653 OUT_RING(start
| (stride
<< RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT
));
2654 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG
, (sz
- 1)));
2655 OUT_RING_TABLE(cmdbuf
->buf
, sz
);
2658 cmdbuf
->buf
+= sz
* sizeof(int);
2659 cmdbuf
->bufsz
-= sz
* sizeof(int);
2663 static int radeon_emit_packet3(drm_device_t
* dev
,
2664 drm_file_t
* filp_priv
,
2665 drm_radeon_cmd_buffer_t
* cmdbuf
)
2667 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2674 if ((ret
= radeon_check_and_fixup_packet3(dev_priv
, filp_priv
,
2676 DRM_ERROR("Packet verification failed\n");
2681 OUT_RING_TABLE(cmdbuf
->buf
, cmdsz
);
2684 cmdbuf
->buf
+= cmdsz
* 4;
2685 cmdbuf
->bufsz
-= cmdsz
* 4;
2689 static int radeon_emit_packet3_cliprect(drm_device_t
* dev
,
2690 drm_file_t
* filp_priv
,
2691 drm_radeon_cmd_buffer_t
* cmdbuf
,
2694 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2695 drm_clip_rect_t box
;
2698 drm_clip_rect_t __user
*boxes
= cmdbuf
->boxes
;
2704 if ((ret
= radeon_check_and_fixup_packet3(dev_priv
, filp_priv
,
2706 DRM_ERROR("Packet verification failed\n");
2714 if (i
< cmdbuf
->nbox
) {
2715 if (DRM_COPY_FROM_USER(&box
, &boxes
[i
], sizeof(box
)))
2716 return DRM_ERR(EFAULT
);
2717 /* FIXME The second and subsequent times round
2718 * this loop, send a WAIT_UNTIL_3D_IDLE before
2719 * calling emit_clip_rect(). This fixes a
2720 * lockup on fast machines when sending
2721 * several cliprects with a cmdbuf, as when
2722 * waving a 2D window over a 3D
2723 * window. Something in the commands from user
2724 * space seems to hang the card when they're
2725 * sent several times in a row. That would be
2726 * the correct place to fix it but this works
2727 * around it until I can figure that out - Tim
2731 RADEON_WAIT_UNTIL_3D_IDLE();
2734 radeon_emit_clip_rect(dev_priv
, &box
);
2738 OUT_RING_TABLE(cmdbuf
->buf
, cmdsz
);
2741 } while (++i
< cmdbuf
->nbox
);
2742 if (cmdbuf
->nbox
== 1)
2746 cmdbuf
->buf
+= cmdsz
* 4;
2747 cmdbuf
->bufsz
-= cmdsz
* 4;
2751 static int radeon_emit_wait(drm_device_t
* dev
, int flags
)
2753 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2756 DRM_DEBUG("%s: %x\n", __FUNCTION__
, flags
);
2758 case RADEON_WAIT_2D
:
2760 RADEON_WAIT_UNTIL_2D_IDLE();
2763 case RADEON_WAIT_3D
:
2765 RADEON_WAIT_UNTIL_3D_IDLE();
2768 case RADEON_WAIT_2D
| RADEON_WAIT_3D
:
2770 RADEON_WAIT_UNTIL_IDLE();
2774 return DRM_ERR(EINVAL
);
2780 static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS
)
2783 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2784 drm_file_t
*filp_priv
;
2785 drm_device_dma_t
*dma
= dev
->dma
;
2786 drm_buf_t
*buf
= NULL
;
2788 drm_radeon_cmd_buffer_t cmdbuf
;
2789 drm_radeon_cmd_header_t header
;
2790 int orig_nbox
, orig_bufsz
;
2793 LOCK_TEST_WITH_RETURN(dev
, filp
);
2796 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2797 return DRM_ERR(EINVAL
);
2800 DRM_GET_PRIV_WITH_RETURN(filp_priv
, filp
);
2802 DRM_COPY_FROM_USER_IOCTL(cmdbuf
,
2803 (drm_radeon_cmd_buffer_t __user
*) data
,
2806 RING_SPACE_TEST_WITH_RETURN(dev_priv
);
2807 VB_AGE_TEST_WITH_RETURN(dev_priv
);
2809 if (cmdbuf
.bufsz
> 64 * 1024 || cmdbuf
.bufsz
< 0) {
2810 return DRM_ERR(EINVAL
);
2813 /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid
2814 * races between checking values and using those values in other code,
2815 * and simply to avoid a lot of function calls to copy in data.
2817 orig_bufsz
= cmdbuf
.bufsz
;
2818 if (orig_bufsz
!= 0) {
2819 kbuf
= drm_alloc(cmdbuf
.bufsz
, DRM_MEM_DRIVER
);
2821 return DRM_ERR(ENOMEM
);
2822 if (DRM_COPY_FROM_USER(kbuf
, cmdbuf
.buf
, cmdbuf
.bufsz
)) {
2823 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2824 return DRM_ERR(EFAULT
);
2829 orig_nbox
= cmdbuf
.nbox
;
2831 if (dev_priv
->microcode_version
== UCODE_R300
) {
2833 temp
= r300_do_cp_cmdbuf(dev
, filp
, filp_priv
, &cmdbuf
);
2835 if (orig_bufsz
!= 0)
2836 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2841 /* microcode_version != r300 */
2842 while (cmdbuf
.bufsz
>= sizeof(header
)) {
2844 header
.i
= *(int *)cmdbuf
.buf
;
2845 cmdbuf
.buf
+= sizeof(header
);
2846 cmdbuf
.bufsz
-= sizeof(header
);
2848 switch (header
.header
.cmd_type
) {
2849 case RADEON_CMD_PACKET
:
2850 DRM_DEBUG("RADEON_CMD_PACKET\n");
2851 if (radeon_emit_packets
2852 (dev_priv
, filp_priv
, header
, &cmdbuf
)) {
2853 DRM_ERROR("radeon_emit_packets failed\n");
2858 case RADEON_CMD_SCALARS
:
2859 DRM_DEBUG("RADEON_CMD_SCALARS\n");
2860 if (radeon_emit_scalars(dev_priv
, header
, &cmdbuf
)) {
2861 DRM_ERROR("radeon_emit_scalars failed\n");
2866 case RADEON_CMD_VECTORS
:
2867 DRM_DEBUG("RADEON_CMD_VECTORS\n");
2868 if (radeon_emit_vectors(dev_priv
, header
, &cmdbuf
)) {
2869 DRM_ERROR("radeon_emit_vectors failed\n");
2874 case RADEON_CMD_DMA_DISCARD
:
2875 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2876 idx
= header
.dma
.buf_idx
;
2877 if (idx
< 0 || idx
>= dma
->buf_count
) {
2878 DRM_ERROR("buffer index %d (of %d max)\n",
2879 idx
, dma
->buf_count
- 1);
2883 buf
= dma
->buflist
[idx
];
2884 if (buf
->filp
!= filp
|| buf
->pending
) {
2885 DRM_ERROR("bad buffer %p %p %d\n",
2886 buf
->filp
, filp
, buf
->pending
);
2890 radeon_cp_discard_buffer(dev
, buf
);
2893 case RADEON_CMD_PACKET3
:
2894 DRM_DEBUG("RADEON_CMD_PACKET3\n");
2895 if (radeon_emit_packet3(dev
, filp_priv
, &cmdbuf
)) {
2896 DRM_ERROR("radeon_emit_packet3 failed\n");
2901 case RADEON_CMD_PACKET3_CLIP
:
2902 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2903 if (radeon_emit_packet3_cliprect
2904 (dev
, filp_priv
, &cmdbuf
, orig_nbox
)) {
2905 DRM_ERROR("radeon_emit_packet3_clip failed\n");
2910 case RADEON_CMD_SCALARS2
:
2911 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2912 if (radeon_emit_scalars2(dev_priv
, header
, &cmdbuf
)) {
2913 DRM_ERROR("radeon_emit_scalars2 failed\n");
2918 case RADEON_CMD_WAIT
:
2919 DRM_DEBUG("RADEON_CMD_WAIT\n");
2920 if (radeon_emit_wait(dev
, header
.wait
.flags
)) {
2921 DRM_ERROR("radeon_emit_wait failed\n");
2926 DRM_ERROR("bad cmd_type %d at %p\n",
2927 header
.header
.cmd_type
,
2928 cmdbuf
.buf
- sizeof(header
));
2933 if (orig_bufsz
!= 0)
2934 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2936 DRM_DEBUG("DONE\n");
2941 if (orig_bufsz
!= 0)
2942 drm_free(kbuf
, orig_bufsz
, DRM_MEM_DRIVER
);
2943 return DRM_ERR(EINVAL
);
2946 static int radeon_cp_getparam(DRM_IOCTL_ARGS
)
2949 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
2950 drm_radeon_getparam_t param
;
2954 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
2955 return DRM_ERR(EINVAL
);
2958 DRM_COPY_FROM_USER_IOCTL(param
, (drm_radeon_getparam_t __user
*) data
,
2961 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID
);
2963 switch (param
.param
) {
2964 case RADEON_PARAM_GART_BUFFER_OFFSET
:
2965 value
= dev_priv
->gart_buffers_offset
;
2967 case RADEON_PARAM_LAST_FRAME
:
2968 dev_priv
->stats
.last_frame_reads
++;
2969 value
= GET_SCRATCH(0);
2971 case RADEON_PARAM_LAST_DISPATCH
:
2972 value
= GET_SCRATCH(1);
2974 case RADEON_PARAM_LAST_CLEAR
:
2975 dev_priv
->stats
.last_clear_reads
++;
2976 value
= GET_SCRATCH(2);
2978 case RADEON_PARAM_IRQ_NR
:
2981 case RADEON_PARAM_GART_BASE
:
2982 value
= dev_priv
->gart_vm_start
;
2984 case RADEON_PARAM_REGISTER_HANDLE
:
2985 value
= dev_priv
->mmio_offset
;
2987 case RADEON_PARAM_STATUS_HANDLE
:
2988 value
= dev_priv
->ring_rptr_offset
;
2990 #if BITS_PER_LONG == 32
2992 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
2993 * pointer which can't fit into an int-sized variable. According to
2994 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
2995 * not supporting it shouldn't be a problem. If the same functionality
2996 * is needed on 64-bit platforms, a new ioctl() would have to be added,
2997 * so backwards-compatibility for the embedded platforms can be
2998 * maintained. --davidm 4-Feb-2004.
3000 case RADEON_PARAM_SAREA_HANDLE
:
3001 /* The lock is the first dword in the sarea. */
3002 value
= (long)dev
->lock
.hw_lock
;
3005 case RADEON_PARAM_GART_TEX_HANDLE
:
3006 value
= dev_priv
->gart_textures_offset
;
3009 return DRM_ERR(EINVAL
);
3012 if (DRM_COPY_TO_USER(param
.value
, &value
, sizeof(int))) {
3013 DRM_ERROR("copy_to_user\n");
3014 return DRM_ERR(EFAULT
);
3020 static int radeon_cp_setparam(DRM_IOCTL_ARGS
)
3023 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3024 drm_file_t
*filp_priv
;
3025 drm_radeon_setparam_t sp
;
3026 struct drm_radeon_driver_file_fields
*radeon_priv
;
3029 DRM_ERROR("%s called with no initialization\n", __FUNCTION__
);
3030 return DRM_ERR(EINVAL
);
3033 DRM_GET_PRIV_WITH_RETURN(filp_priv
, filp
);
3035 DRM_COPY_FROM_USER_IOCTL(sp
, (drm_radeon_setparam_t __user
*) data
,
3039 case RADEON_SETPARAM_FB_LOCATION
:
3040 radeon_priv
= filp_priv
->driver_priv
;
3041 radeon_priv
->radeon_fb_delta
= dev_priv
->fb_location
- sp
.value
;
3043 case RADEON_SETPARAM_SWITCH_TILING
:
3044 if (sp
.value
== 0) {
3045 DRM_DEBUG("color tiling disabled\n");
3046 dev_priv
->front_pitch_offset
&= ~RADEON_DST_TILE_MACRO
;
3047 dev_priv
->back_pitch_offset
&= ~RADEON_DST_TILE_MACRO
;
3048 dev_priv
->sarea_priv
->tiling_enabled
= 0;
3049 } else if (sp
.value
== 1) {
3050 DRM_DEBUG("color tiling enabled\n");
3051 dev_priv
->front_pitch_offset
|= RADEON_DST_TILE_MACRO
;
3052 dev_priv
->back_pitch_offset
|= RADEON_DST_TILE_MACRO
;
3053 dev_priv
->sarea_priv
->tiling_enabled
= 1;
3056 case RADEON_SETPARAM_PCIGART_LOCATION
:
3057 dev_priv
->pcigart_offset
= sp
.value
;
3060 DRM_DEBUG("Invalid parameter %d\n", sp
.param
);
3061 return DRM_ERR(EINVAL
);
3067 /* When a client dies:
3068 * - Check for and clean up flipped page state
3069 * - Free any alloced GART memory.
3071 * DRM infrastructure takes care of reclaiming dma buffers.
3073 void radeon_driver_prerelease(drm_device_t
* dev
, DRMFILE filp
)
3075 if (dev
->dev_private
) {
3076 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3077 if (dev_priv
->page_flipping
) {
3078 radeon_do_cleanup_pageflip(dev
);
3080 radeon_mem_release(filp
, dev_priv
->gart_heap
);
3081 radeon_mem_release(filp
, dev_priv
->fb_heap
);
3082 radeon_surfaces_release(filp
, dev_priv
);
3086 void radeon_driver_pretakedown(drm_device_t
* dev
)
3088 radeon_do_release(dev
);
3091 int radeon_driver_open_helper(drm_device_t
* dev
, drm_file_t
* filp_priv
)
3093 drm_radeon_private_t
*dev_priv
= dev
->dev_private
;
3094 struct drm_radeon_driver_file_fields
*radeon_priv
;
3097 (struct drm_radeon_driver_file_fields
*)
3098 drm_alloc(sizeof(*radeon_priv
), DRM_MEM_FILES
);
3103 filp_priv
->driver_priv
= radeon_priv
;
3105 radeon_priv
->radeon_fb_delta
= dev_priv
->fb_location
;
3107 radeon_priv
->radeon_fb_delta
= 0;
3111 void radeon_driver_free_filp_priv(drm_device_t
* dev
, drm_file_t
* filp_priv
)
3113 struct drm_radeon_driver_file_fields
*radeon_priv
=
3114 filp_priv
->driver_priv
;
3116 drm_free(radeon_priv
, sizeof(*radeon_priv
), DRM_MEM_FILES
);
3119 drm_ioctl_desc_t radeon_ioctls
[] = {
3120 [DRM_IOCTL_NR(DRM_RADEON_CP_INIT
)] = {radeon_cp_init
, 1, 1}
3122 [DRM_IOCTL_NR(DRM_RADEON_CP_START
)] = {radeon_cp_start
, 1, 1}
3124 [DRM_IOCTL_NR(DRM_RADEON_CP_STOP
)] = {radeon_cp_stop
, 1, 1}
3126 [DRM_IOCTL_NR(DRM_RADEON_CP_RESET
)] = {radeon_cp_reset
, 1, 1}
3128 [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE
)] = {radeon_cp_idle
, 1, 0}
3130 [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME
)] = {radeon_cp_resume
, 1, 0}
3132 [DRM_IOCTL_NR(DRM_RADEON_RESET
)] = {radeon_engine_reset
, 1, 0}
3134 [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN
)] = {radeon_fullscreen
, 1, 0}
3136 [DRM_IOCTL_NR(DRM_RADEON_SWAP
)] = {radeon_cp_swap
, 1, 0}
3138 [DRM_IOCTL_NR(DRM_RADEON_CLEAR
)] = {radeon_cp_clear
, 1, 0}
3140 [DRM_IOCTL_NR(DRM_RADEON_VERTEX
)] = {radeon_cp_vertex
, 1, 0}
3142 [DRM_IOCTL_NR(DRM_RADEON_INDICES
)] = {radeon_cp_indices
, 1, 0}
3144 [DRM_IOCTL_NR(DRM_RADEON_TEXTURE
)] = {radeon_cp_texture
, 1, 0}
3146 [DRM_IOCTL_NR(DRM_RADEON_STIPPLE
)] = {radeon_cp_stipple
, 1, 0}
3148 [DRM_IOCTL_NR(DRM_RADEON_INDIRECT
)] = {radeon_cp_indirect
, 1, 1}
3150 [DRM_IOCTL_NR(DRM_RADEON_VERTEX2
)] = {radeon_cp_vertex2
, 1, 0}
3152 [DRM_IOCTL_NR(DRM_RADEON_CMDBUF
)] = {radeon_cp_cmdbuf
, 1, 0}
3154 [DRM_IOCTL_NR(DRM_RADEON_GETPARAM
)] = {radeon_cp_getparam
, 1, 0}
3156 [DRM_IOCTL_NR(DRM_RADEON_FLIP
)] = {radeon_cp_flip
, 1, 0}
3158 [DRM_IOCTL_NR(DRM_RADEON_ALLOC
)] = {radeon_mem_alloc
, 1, 0}
3160 [DRM_IOCTL_NR(DRM_RADEON_FREE
)] = {radeon_mem_free
, 1, 0}
3162 [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP
)] = {radeon_mem_init_heap
, 1, 1}
3164 [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT
)] = {radeon_irq_emit
, 1, 0}
3166 [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT
)] = {radeon_irq_wait
, 1, 0}
3168 [DRM_IOCTL_NR(DRM_RADEON_SETPARAM
)] = {radeon_cp_setparam
, 1, 0}
3170 [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC
)] = {radeon_surface_alloc
, 1, 0}
3172 [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE
)] = {radeon_surface_free
, 1, 0}
3175 int radeon_max_ioctl
= DRM_ARRAY_SIZE(radeon_ioctls
);