2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
33 * \author Nicolai Haehnle <prefect_@gmx.net>
36 #include "main/glheader.h"
37 #include "main/state.h"
38 #include "main/imports.h"
39 #include "main/macros.h"
40 #include "main/context.h"
41 #include "main/simple_list.h"
42 #include "swrast/swrast.h"
45 #include "radeon_drm.h"
47 #include "radeon_ioctl.h"
48 #include "r300_context.h"
49 #include "r300_ioctl.h"
50 #include "radeon_reg.h"
52 #include "r300_cmdbuf.h"
53 #include "r300_emit.h"
54 #include "r300_state.h"
56 // Set this to 1 for extremely verbose debugging of command buffers
57 #define DEBUG_CMDBUF 0
60 * Send the current command buffer via ioctl to the hardware.
62 int r300FlushCmdBufLocked(r300ContextPtr r300
, const char *caller
)
66 drm_radeon_cmd_buffer_t cmd
;
69 if (r300
->radeon
.lost_context
) {
71 r300
->radeon
.lost_context
= GL_FALSE
;
73 start
= r300
->cmdbuf
.count_reemit
;
75 if (RADEON_DEBUG
& DEBUG_IOCTL
) {
76 fprintf(stderr
, "%s from %s - %i cliprects\n",
77 __FUNCTION__
, caller
, r300
->radeon
.numClipRects
);
79 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_VERBOSE
)
80 for (i
= start
; i
< r300
->cmdbuf
.count_used
; ++i
)
81 fprintf(stderr
, "%d: %08x\n", i
,
82 r300
->cmdbuf
.cmd_buf
[i
]);
85 cmd
.buf
= (char *)(r300
->cmdbuf
.cmd_buf
+ start
);
86 cmd
.bufsz
= (r300
->cmdbuf
.count_used
- start
) * 4;
88 if (r300
->radeon
.state
.scissor
.enabled
) {
89 cmd
.nbox
= r300
->radeon
.state
.scissor
.numClipRects
;
91 (drm_clip_rect_t
*) r300
->radeon
.state
.scissor
.pClipRects
;
93 cmd
.nbox
= r300
->radeon
.numClipRects
;
94 cmd
.boxes
= (drm_clip_rect_t
*) r300
->radeon
.pClipRects
;
97 ret
= drmCommandWrite(r300
->radeon
.dri
.fd
,
98 DRM_RADEON_CMDBUF
, &cmd
, sizeof(cmd
));
100 if (RADEON_DEBUG
& DEBUG_SYNC
) {
101 fprintf(stderr
, "Syncing in %s (from %s)\n\n",
102 __FUNCTION__
, caller
);
103 radeonWaitForIdleLocked(&r300
->radeon
);
106 r300
->dma
.nr_released_bufs
= 0;
107 r300
->cmdbuf
.count_used
= 0;
108 r300
->cmdbuf
.count_reemit
= 0;
113 int r300FlushCmdBuf(r300ContextPtr r300
, const char *caller
)
117 LOCK_HARDWARE(&r300
->radeon
);
119 ret
= r300FlushCmdBufLocked(r300
, caller
);
121 UNLOCK_HARDWARE(&r300
->radeon
);
124 fprintf(stderr
, "drmRadeonCmdBuffer: %d\n", ret
);
131 static void r300PrintStateAtom(r300ContextPtr r300
, struct r300_state_atom
*state
)
134 int dwords
= (*state
->check
) (r300
, state
);
136 fprintf(stderr
, " emit %s %d/%d\n", state
->name
, dwords
,
139 if (RADEON_DEBUG
& DEBUG_VERBOSE
) {
140 for (i
= 0; i
< dwords
; i
++) {
141 fprintf(stderr
, " %s[%d]: %08x\n",
142 state
->name
, i
, state
->cmd
[i
]);
148 * Emit all atoms with a dirty field equal to dirty.
150 * The caller must have ensured that there is enough space in the command
153 static INLINE
void r300EmitAtoms(r300ContextPtr r300
, GLboolean dirty
)
155 struct r300_state_atom
*atom
;
159 dest
= r300
->cmdbuf
.cmd_buf
+ r300
->cmdbuf
.count_used
;
162 *dest
= cmdwait(R300_WAIT_3D
| R300_WAIT_3D_CLEAN
);
164 r300
->cmdbuf
.count_used
++;
166 /* Emit cache flush */
167 *dest
= cmdpacket0(R300_TX_INVALTAGS
, 1);
169 r300
->cmdbuf
.count_used
++;
171 *dest
= R300_TX_FLUSH
;
173 r300
->cmdbuf
.count_used
++;
178 r300
->cmdbuf
.count_used
++;
180 /* Emit actual atoms */
182 foreach(atom
, &r300
->hw
.atomlist
) {
183 if ((atom
->dirty
|| r300
->hw
.all_dirty
) == dirty
) {
184 dwords
= (*atom
->check
) (r300
, atom
);
186 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
187 r300PrintStateAtom(r300
, atom
);
189 memcpy(dest
, atom
->cmd
, dwords
* 4);
191 r300
->cmdbuf
.count_used
+= dwords
;
192 atom
->dirty
= GL_FALSE
;
194 if (DEBUG_CMDBUF
&& RADEON_DEBUG
& DEBUG_STATE
) {
195 fprintf(stderr
, " skip state %s\n",
204 * Copy dirty hardware state atoms into the command buffer.
206 * We also copy out clean state if we're at the start of a buffer. That makes
207 * it easy to recover from lost contexts.
209 void r300EmitState(r300ContextPtr r300
)
211 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_PRIMS
))
212 fprintf(stderr
, "%s\n", __FUNCTION__
);
214 if (r300
->cmdbuf
.count_used
&& !r300
->hw
.is_dirty
215 && !r300
->hw
.all_dirty
)
218 /* To avoid going across the entire set of states multiple times, just check
219 * for enough space for the case of emitting all state, and inline the
220 * r300AllocCmdBuf code here without all the checks.
222 r300EnsureCmdBufSpace(r300
, r300
->hw
.max_state_size
, __FUNCTION__
);
224 if (!r300
->cmdbuf
.count_used
) {
225 if (RADEON_DEBUG
& DEBUG_STATE
)
226 fprintf(stderr
, "Begin reemit state\n");
228 r300EmitAtoms(r300
, GL_FALSE
);
229 r300
->cmdbuf
.count_reemit
= r300
->cmdbuf
.count_used
;
232 if (RADEON_DEBUG
& DEBUG_STATE
)
233 fprintf(stderr
, "Begin dirty state\n");
235 r300EmitAtoms(r300
, GL_TRUE
);
237 assert(r300
->cmdbuf
.count_used
< r300
->cmdbuf
.size
);
239 r300
->hw
.is_dirty
= GL_FALSE
;
240 r300
->hw
.all_dirty
= GL_FALSE
;
243 #define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count)
244 #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
245 #define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count)
247 static int check_always(r300ContextPtr r300
, struct r300_state_atom
*atom
)
249 return atom
->cmd_size
;
252 static int check_variable(r300ContextPtr r300
, struct r300_state_atom
*atom
)
255 cnt
= packet0_count(atom
->cmd
);
256 return cnt
? cnt
+ 1 : 0;
259 static int check_vpu(r300ContextPtr r300
, struct r300_state_atom
*atom
)
262 cnt
= vpu_count(atom
->cmd
);
263 return cnt
? (cnt
* 4) + 1 : 0;
266 static int check_r500fp(r300ContextPtr r300
, struct r300_state_atom
*atom
)
269 cnt
= r500fp_count(atom
->cmd
);
270 return cnt
? (cnt
* 6) + 1 : 0;
273 static int check_r500fp_const(r300ContextPtr r300
, struct r300_state_atom
*atom
)
276 cnt
= r500fp_count(atom
->cmd
);
277 return cnt
? (cnt
* 4) + 1 : 0;
280 #define ALLOC_STATE( ATOM, CHK, SZ, IDX ) \
282 r300->hw.ATOM.cmd_size = (SZ); \
283 r300->hw.ATOM.cmd = (uint32_t*)CALLOC((SZ) * sizeof(uint32_t)); \
284 r300->hw.ATOM.name = #ATOM; \
285 r300->hw.ATOM.idx = (IDX); \
286 r300->hw.ATOM.check = check_##CHK; \
287 r300->hw.ATOM.dirty = GL_FALSE; \
288 r300->hw.max_state_size += (SZ); \
289 insert_at_tail(&r300->hw.atomlist, &r300->hw.ATOM); \
292 * Allocate memory for the command buffer and initialize the state atom
293 * list. Note that the initial hardware state is set by r300InitState().
295 void r300InitCmdBuf(r300ContextPtr r300
)
302 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
305 if (r300
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
308 r300
->hw
.max_state_size
= 2 + 2; /* reserve extra space for WAIT_IDLE and tex cache flush */
310 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
311 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
312 fprintf(stderr
, "Using %d maximum texture units..\n", mtu
);
315 /* Setup the atom linked list */
316 make_empty_list(&r300
->hw
.atomlist
);
317 r300
->hw
.atomlist
.name
= "atom-list";
319 /* Initialize state atoms */
320 ALLOC_STATE(vpt
, always
, R300_VPT_CMDSIZE
, 0);
321 r300
->hw
.vpt
.cmd
[R300_VPT_CMD_0
] = cmdpacket0(R300_SE_VPORT_XSCALE
, 6);
322 ALLOC_STATE(vap_cntl
, always
, R300_VAP_CNTL_SIZE
, 0);
323 r300
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_FLUSH
] = cmdpacket0(R300_VAP_PVS_STATE_FLUSH_REG
, 1);
324 r300
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_FLUSH_1
] = 0;
325 r300
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_CMD
] = cmdpacket0(R300_VAP_CNTL
, 1);
327 ALLOC_STATE(vap_index_offset
, always
, 2, 0);
328 r300
->hw
.vap_index_offset
.cmd
[0] = cmdpacket0(R500_VAP_INDEX_OFFSET
, 1);
329 r300
->hw
.vap_index_offset
.cmd
[1] = 0;
331 ALLOC_STATE(vte
, always
, 3, 0);
332 r300
->hw
.vte
.cmd
[0] = cmdpacket0(R300_SE_VTE_CNTL
, 2);
333 ALLOC_STATE(vap_vf_max_vtx_indx
, always
, 3, 0);
334 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[0] = cmdpacket0(R300_VAP_VF_MAX_VTX_INDX
, 2);
335 ALLOC_STATE(vap_cntl_status
, always
, 2, 0);
336 r300
->hw
.vap_cntl_status
.cmd
[0] = cmdpacket0(R300_VAP_CNTL_STATUS
, 1);
337 ALLOC_STATE(vir
[0], variable
, R300_VIR_CMDSIZE
, 0);
338 r300
->hw
.vir
[0].cmd
[R300_VIR_CMD_0
] =
339 cmdpacket0(R300_VAP_PROG_STREAM_CNTL_0
, 1);
340 ALLOC_STATE(vir
[1], variable
, R300_VIR_CMDSIZE
, 1);
341 r300
->hw
.vir
[1].cmd
[R300_VIR_CMD_0
] =
342 cmdpacket0(R300_VAP_PROG_STREAM_CNTL_EXT_0
, 1);
343 ALLOC_STATE(vic
, always
, R300_VIC_CMDSIZE
, 0);
344 r300
->hw
.vic
.cmd
[R300_VIC_CMD_0
] = cmdpacket0(R300_VAP_VTX_STATE_CNTL
, 2);
345 ALLOC_STATE(vap_psc_sgn_norm_cntl
, always
, 2, 0);
346 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[0] = cmdpacket0(R300_VAP_PSC_SGN_NORM_CNTL
, SGN_NORM_ZERO_CLAMP_MINUS_ONE
);
349 ALLOC_STATE(vap_clip_cntl
, always
, 2, 0);
350 r300
->hw
.vap_clip_cntl
.cmd
[0] = cmdpacket0(R300_VAP_CLIP_CNTL
, 1);
351 ALLOC_STATE(vap_clip
, always
, 5, 0);
352 r300
->hw
.vap_clip
.cmd
[0] = cmdpacket0(R300_VAP_GB_VERT_CLIP_ADJ
, 4);
353 ALLOC_STATE(vap_pvs_vtx_timeout_reg
, always
, 2, 0);
354 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[0] = cmdpacket0(VAP_PVS_VTX_TIMEOUT_REG
, 1);
357 ALLOC_STATE(vof
, always
, R300_VOF_CMDSIZE
, 0);
358 r300
->hw
.vof
.cmd
[R300_VOF_CMD_0
] =
359 cmdpacket0(R300_VAP_OUTPUT_VTX_FMT_0
, 2);
362 ALLOC_STATE(pvs
, always
, R300_PVS_CMDSIZE
, 0);
363 r300
->hw
.pvs
.cmd
[R300_PVS_CMD_0
] =
364 cmdpacket0(R300_VAP_PVS_CODE_CNTL_0
, 3);
367 ALLOC_STATE(gb_enable
, always
, 2, 0);
368 r300
->hw
.gb_enable
.cmd
[0] = cmdpacket0(R300_GB_ENABLE
, 1);
369 ALLOC_STATE(gb_misc
, always
, R300_GB_MISC_CMDSIZE
, 0);
370 r300
->hw
.gb_misc
.cmd
[0] = cmdpacket0(R300_GB_MSPOS0
, 5);
371 ALLOC_STATE(txe
, always
, R300_TXE_CMDSIZE
, 0);
372 r300
->hw
.txe
.cmd
[R300_TXE_CMD_0
] = cmdpacket0(R300_TX_ENABLE
, 1);
373 ALLOC_STATE(ga_point_s0
, always
, 5, 0);
374 r300
->hw
.ga_point_s0
.cmd
[0] = cmdpacket0(R300_GA_POINT_S0
, 4);
375 ALLOC_STATE(ga_triangle_stipple
, always
, 2, 0);
376 r300
->hw
.ga_triangle_stipple
.cmd
[0] = cmdpacket0(R300_GA_TRIANGLE_STIPPLE
, 1);
377 ALLOC_STATE(ps
, always
, R300_PS_CMDSIZE
, 0);
378 r300
->hw
.ps
.cmd
[0] = cmdpacket0(R300_GA_POINT_SIZE
, 1);
379 ALLOC_STATE(ga_point_minmax
, always
, 4, 0);
380 r300
->hw
.ga_point_minmax
.cmd
[0] = cmdpacket0(R300_GA_POINT_MINMAX
, 3);
381 ALLOC_STATE(lcntl
, always
, 2, 0);
382 r300
->hw
.lcntl
.cmd
[0] = cmdpacket0(R300_GA_LINE_CNTL
, 1);
383 ALLOC_STATE(ga_line_stipple
, always
, 4, 0);
384 r300
->hw
.ga_line_stipple
.cmd
[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE
, 3);
385 ALLOC_STATE(shade
, always
, 5, 0);
386 r300
->hw
.shade
.cmd
[0] = cmdpacket0(R300_GA_ENHANCE
, 4);
387 ALLOC_STATE(polygon_mode
, always
, 4, 0);
388 r300
->hw
.polygon_mode
.cmd
[0] = cmdpacket0(R300_GA_POLY_MODE
, 3);
389 ALLOC_STATE(fogp
, always
, 3, 0);
390 r300
->hw
.fogp
.cmd
[0] = cmdpacket0(R300_GA_FOG_SCALE
, 2);
391 ALLOC_STATE(zbias_cntl
, always
, 2, 0);
392 r300
->hw
.zbias_cntl
.cmd
[0] = cmdpacket0(R300_SU_TEX_WRAP
, 1);
393 ALLOC_STATE(zbs
, always
, R300_ZBS_CMDSIZE
, 0);
394 r300
->hw
.zbs
.cmd
[R300_ZBS_CMD_0
] =
395 cmdpacket0(R300_SU_POLY_OFFSET_FRONT_SCALE
, 4);
396 ALLOC_STATE(occlusion_cntl
, always
, 2, 0);
397 r300
->hw
.occlusion_cntl
.cmd
[0] = cmdpacket0(R300_SU_POLY_OFFSET_ENABLE
, 1);
398 ALLOC_STATE(cul
, always
, R300_CUL_CMDSIZE
, 0);
399 r300
->hw
.cul
.cmd
[R300_CUL_CMD_0
] = cmdpacket0(R300_SU_CULL_MODE
, 1);
400 ALLOC_STATE(su_depth_scale
, always
, 3, 0);
401 r300
->hw
.su_depth_scale
.cmd
[0] = cmdpacket0(R300_SU_DEPTH_SCALE
, 2);
402 ALLOC_STATE(rc
, always
, R300_RC_CMDSIZE
, 0);
403 r300
->hw
.rc
.cmd
[R300_RC_CMD_0
] = cmdpacket0(R300_RS_COUNT
, 2);
405 ALLOC_STATE(ri
, always
, R500_RI_CMDSIZE
, 0);
406 r300
->hw
.ri
.cmd
[R300_RI_CMD_0
] = cmdpacket0(R500_RS_IP_0
, 16);
407 for (i
= 0; i
< 8; i
++) {
408 r300
->hw
.ri
.cmd
[R300_RI_CMD_0
+ i
+1] =
409 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
410 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
411 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
412 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
414 ALLOC_STATE(rr
, variable
, R300_RR_CMDSIZE
, 0);
415 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R500_RS_INST_0
, 1);
417 ALLOC_STATE(ri
, always
, R300_RI_CMDSIZE
, 0);
418 r300
->hw
.ri
.cmd
[R300_RI_CMD_0
] = cmdpacket0(R300_RS_IP_0
, 8);
419 ALLOC_STATE(rr
, variable
, R300_RR_CMDSIZE
, 0);
420 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_INST_0
, 1);
422 ALLOC_STATE(sc_hyperz
, always
, 3, 0);
423 r300
->hw
.sc_hyperz
.cmd
[0] = cmdpacket0(R300_SC_HYPERZ
, 2);
424 ALLOC_STATE(sc_screendoor
, always
, 2, 0);
425 r300
->hw
.sc_screendoor
.cmd
[0] = cmdpacket0(R300_SC_SCREENDOOR
, 1);
426 ALLOC_STATE(us_out_fmt
, always
, 6, 0);
427 r300
->hw
.us_out_fmt
.cmd
[0] = cmdpacket0(R300_US_OUT_FMT
, 5);
430 ALLOC_STATE(fp
, always
, R500_FP_CMDSIZE
, 0);
431 r300
->hw
.fp
.cmd
[R500_FP_CMD_0
] = cmdpacket0(R500_US_CONFIG
, 2);
432 r300
->hw
.fp
.cmd
[R500_FP_CNTL
] = R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO
;
433 r300
->hw
.fp
.cmd
[R500_FP_CMD_1
] = cmdpacket0(R500_US_CODE_ADDR
, 3);
434 r300
->hw
.fp
.cmd
[R500_FP_CMD_2
] = cmdpacket0(R500_US_FC_CTRL
, 1);
435 r300
->hw
.fp
.cmd
[R500_FP_FC_CNTL
] = 0; /* FIXME when we add flow control */
437 ALLOC_STATE(r500fp
, r500fp
, R500_FPI_CMDSIZE
, 0);
438 r300
->hw
.r500fp
.cmd
[R300_FPI_CMD_0
] = cmdr500fp(0, 0, 0, 0);
439 ALLOC_STATE(r500fp_const
, r500fp_const
, R500_FPP_CMDSIZE
, 0);
440 r300
->hw
.r500fp_const
.cmd
[R300_FPI_CMD_0
] = cmdr500fp(0, 0, 1, 0);
442 ALLOC_STATE(fp
, always
, R300_FP_CMDSIZE
, 0);
443 r300
->hw
.fp
.cmd
[R300_FP_CMD_0
] = cmdpacket0(R300_US_CONFIG
, 3);
444 r300
->hw
.fp
.cmd
[R300_FP_CMD_1
] = cmdpacket0(R300_US_CODE_ADDR_0
, 4);
445 ALLOC_STATE(fpt
, variable
, R300_FPT_CMDSIZE
, 0);
446 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_US_TEX_INST_0
, 0);
448 ALLOC_STATE(fpi
[0], variable
, R300_FPI_CMDSIZE
, 0);
449 r300
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_INST_0
, 1);
450 ALLOC_STATE(fpi
[1], variable
, R300_FPI_CMDSIZE
, 1);
451 r300
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_RGB_ADDR_0
, 1);
452 ALLOC_STATE(fpi
[2], variable
, R300_FPI_CMDSIZE
, 2);
453 r300
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_INST_0
, 1);
454 ALLOC_STATE(fpi
[3], variable
, R300_FPI_CMDSIZE
, 3);
455 r300
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0
, 1);
456 ALLOC_STATE(fpp
, variable
, R300_FPP_CMDSIZE
, 0);
457 r300
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, 0);
459 ALLOC_STATE(fogs
, always
, R300_FOGS_CMDSIZE
, 0);
460 r300
->hw
.fogs
.cmd
[R300_FOGS_CMD_0
] = cmdpacket0(R300_FG_FOG_BLEND
, 1);
461 ALLOC_STATE(fogc
, always
, R300_FOGC_CMDSIZE
, 0);
462 r300
->hw
.fogc
.cmd
[R300_FOGC_CMD_0
] = cmdpacket0(R300_FG_FOG_COLOR_R
, 3);
463 ALLOC_STATE(at
, always
, R300_AT_CMDSIZE
, 0);
464 r300
->hw
.at
.cmd
[R300_AT_CMD_0
] = cmdpacket0(R300_FG_ALPHA_FUNC
, 2);
465 ALLOC_STATE(fg_depth_src
, always
, 2, 0);
466 r300
->hw
.fg_depth_src
.cmd
[0] = cmdpacket0(R300_FG_DEPTH_SRC
, 1);
467 ALLOC_STATE(rb3d_cctl
, always
, 2, 0);
468 r300
->hw
.rb3d_cctl
.cmd
[0] = cmdpacket0(R300_RB3D_CCTL
, 1);
469 ALLOC_STATE(bld
, always
, R300_BLD_CMDSIZE
, 0);
470 r300
->hw
.bld
.cmd
[R300_BLD_CMD_0
] = cmdpacket0(R300_RB3D_CBLEND
, 2);
471 ALLOC_STATE(cmk
, always
, R300_CMK_CMDSIZE
, 0);
472 r300
->hw
.cmk
.cmd
[R300_CMK_CMD_0
] = cmdpacket0(RB3D_COLOR_CHANNEL_MASK
, 1);
474 ALLOC_STATE(blend_color
, always
, 3, 0);
475 r300
->hw
.blend_color
.cmd
[0] = cmdpacket0(R500_RB3D_CONSTANT_COLOR_AR
, 2);
477 ALLOC_STATE(blend_color
, always
, 2, 0);
478 r300
->hw
.blend_color
.cmd
[0] = cmdpacket0(R300_RB3D_BLEND_COLOR
, 1);
480 ALLOC_STATE(rop
, always
, 2, 0);
481 r300
->hw
.rop
.cmd
[0] = cmdpacket0(R300_RB3D_ROPCNTL
, 1);
482 ALLOC_STATE(cb
, always
, R300_CB_CMDSIZE
, 0);
483 r300
->hw
.cb
.cmd
[R300_CB_CMD_0
] = cmdpacket0(R300_RB3D_COLOROFFSET0
, 1);
484 r300
->hw
.cb
.cmd
[R300_CB_CMD_1
] = cmdpacket0(R300_RB3D_COLORPITCH0
, 1);
485 ALLOC_STATE(rb3d_dither_ctl
, always
, 10, 0);
486 r300
->hw
.rb3d_dither_ctl
.cmd
[0] = cmdpacket0(R300_RB3D_DITHER_CTL
, 9);
487 ALLOC_STATE(rb3d_aaresolve_ctl
, always
, 2, 0);
488 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[0] = cmdpacket0(R300_RB3D_AARESOLVE_CTL
, 1);
489 ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold
, always
, 3, 0);
490 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[0] = cmdpacket0(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
, 2);
491 ALLOC_STATE(zs
, always
, R300_ZS_CMDSIZE
, 0);
492 r300
->hw
.zs
.cmd
[R300_ZS_CMD_0
] =
493 cmdpacket0(R300_ZB_CNTL
, 3);
494 ALLOC_STATE(zstencil_format
, always
, 5, 0);
495 r300
->hw
.zstencil_format
.cmd
[0] =
496 cmdpacket0(R300_ZB_FORMAT
, 4);
497 ALLOC_STATE(zb
, always
, R300_ZB_CMDSIZE
, 0);
498 r300
->hw
.zb
.cmd
[R300_ZB_CMD_0
] = cmdpacket0(R300_ZB_DEPTHOFFSET
, 2);
499 ALLOC_STATE(zb_depthclearvalue
, always
, 2, 0);
500 r300
->hw
.zb_depthclearvalue
.cmd
[0] = cmdpacket0(R300_ZB_DEPTHCLEARVALUE
, 1);
501 ALLOC_STATE(unk4F30
, always
, 3, 0);
502 r300
->hw
.unk4F30
.cmd
[0] = cmdpacket0(0x4F30, 2);
503 ALLOC_STATE(zb_hiz_offset
, always
, 2, 0);
504 r300
->hw
.zb_hiz_offset
.cmd
[0] = cmdpacket0(R300_ZB_HIZ_OFFSET
, 1);
505 ALLOC_STATE(zb_hiz_pitch
, always
, 2, 0);
506 r300
->hw
.zb_hiz_pitch
.cmd
[0] = cmdpacket0(R300_ZB_HIZ_PITCH
, 1);
508 /* VPU only on TCL */
511 ALLOC_STATE(vpi
, vpu
, R300_VPI_CMDSIZE
, 0);
512 r300
->hw
.vpi
.cmd
[R300_VPI_CMD_0
] =
513 cmdvpu(R300_PVS_CODE_START
, 0);
516 ALLOC_STATE(vpp
, vpu
, R300_VPP_CMDSIZE
, 0);
517 r300
->hw
.vpp
.cmd
[R300_VPP_CMD_0
] =
518 cmdvpu(R500_PVS_CONST_START
, 0);
520 ALLOC_STATE(vps
, vpu
, R300_VPS_CMDSIZE
, 0);
521 r300
->hw
.vps
.cmd
[R300_VPS_CMD_0
] =
522 cmdvpu(R500_POINT_VPORT_SCALE_OFFSET
, 1);
524 for (i
= 0; i
< 6; i
++) {
525 ALLOC_STATE(vpucp
[i
], vpu
, R300_VPUCP_CMDSIZE
, 0);
526 r300
->hw
.vpucp
[i
].cmd
[R300_VPUCP_CMD_0
] =
527 cmdvpu(R500_PVS_UCP_START
+ i
, 1);
530 ALLOC_STATE(vpp
, vpu
, R300_VPP_CMDSIZE
, 0);
531 r300
->hw
.vpp
.cmd
[R300_VPP_CMD_0
] =
532 cmdvpu(R300_PVS_CONST_START
, 0);
534 ALLOC_STATE(vps
, vpu
, R300_VPS_CMDSIZE
, 0);
535 r300
->hw
.vps
.cmd
[R300_VPS_CMD_0
] =
536 cmdvpu(R300_POINT_VPORT_SCALE_OFFSET
, 1);
538 for (i
= 0; i
< 6; i
++) {
539 ALLOC_STATE(vpucp
[i
], vpu
, R300_VPUCP_CMDSIZE
, 0);
540 r300
->hw
.vpucp
[i
].cmd
[R300_VPUCP_CMD_0
] =
541 cmdvpu(R300_PVS_UCP_START
+ i
, 1);
547 ALLOC_STATE(tex
.filter
, variable
, mtu
+ 1, 0);
548 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
549 cmdpacket0(R300_TX_FILTER0_0
, 0);
551 ALLOC_STATE(tex
.filter_1
, variable
, mtu
+ 1, 0);
552 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
553 cmdpacket0(R300_TX_FILTER1_0
, 0);
555 ALLOC_STATE(tex
.size
, variable
, mtu
+ 1, 0);
556 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, 0);
558 ALLOC_STATE(tex
.format
, variable
, mtu
+ 1, 0);
559 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
560 cmdpacket0(R300_TX_FORMAT_0
, 0);
562 ALLOC_STATE(tex
.pitch
, variable
, mtu
+ 1, 0);
563 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT2_0
, 0);
565 ALLOC_STATE(tex
.offset
, variable
, mtu
+ 1, 0);
566 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
567 cmdpacket0(R300_TX_OFFSET_0
, 0);
569 ALLOC_STATE(tex
.chroma_key
, variable
, mtu
+ 1, 0);
570 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
571 cmdpacket0(R300_TX_CHROMA_KEY_0
, 0);
573 ALLOC_STATE(tex
.border_color
, variable
, mtu
+ 1, 0);
574 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
575 cmdpacket0(R300_TX_BORDER_COLOR_0
, 0);
577 r300
->hw
.is_dirty
= GL_TRUE
;
578 r300
->hw
.all_dirty
= GL_TRUE
;
580 /* Initialize command buffer */
582 256 * driQueryOptioni(&r300
->radeon
.optionCache
,
583 "command_buffer_size");
584 if (size
< 2 * r300
->hw
.max_state_size
) {
585 size
= 2 * r300
->hw
.max_state_size
+ 65535;
590 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
)) {
591 fprintf(stderr
, "sizeof(drm_r300_cmd_header_t)=%zd\n",
592 sizeof(drm_r300_cmd_header_t
));
593 fprintf(stderr
, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
594 sizeof(drm_radeon_cmd_buffer_t
));
596 "Allocating %d bytes command buffer (max state is %d bytes)\n",
597 size
* 4, r300
->hw
.max_state_size
* 4);
600 r300
->cmdbuf
.size
= size
;
601 r300
->cmdbuf
.cmd_buf
= (uint32_t *) CALLOC(size
* 4);
602 r300
->cmdbuf
.count_used
= 0;
603 r300
->cmdbuf
.count_reemit
= 0;
607 * Destroy the command buffer and state atoms.
609 void r300DestroyCmdBuf(r300ContextPtr r300
)
611 struct r300_state_atom
*atom
;
613 FREE(r300
->cmdbuf
.cmd_buf
);
615 foreach(atom
, &r300
->hw
.atomlist
) {
620 void r300EmitBlit(r300ContextPtr rmesa
,
626 GLint srcx
, GLint srcy
,
627 GLint dstx
, GLint dsty
, GLuint w
, GLuint h
)
629 drm_r300_cmd_header_t
*cmd
;
631 if (RADEON_DEBUG
& DEBUG_IOCTL
)
633 "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
634 __FUNCTION__
, src_pitch
, src_offset
, srcx
, srcy
,
635 dst_pitch
, dst_offset
, dstx
, dsty
, w
, h
);
637 assert((src_pitch
& 63) == 0);
638 assert((dst_pitch
& 63) == 0);
639 assert((src_offset
& 1023) == 0);
640 assert((dst_offset
& 1023) == 0);
641 assert(w
< (1 << 16));
642 assert(h
< (1 << 16));
644 cmd
= (drm_r300_cmd_header_t
*) r300AllocCmdBuf(rmesa
, 8, __FUNCTION__
);
646 cmd
[0].header
.cmd_type
= R300_CMD_PACKET3
;
647 cmd
[0].header
.pad0
= R300_CMD_PACKET3_RAW
;
648 cmd
[1].u
= R300_CP_CMD_BITBLT_MULTI
| (5 << 16);
649 cmd
[2].u
= (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
650 RADEON_GMC_DST_PITCH_OFFSET_CNTL
|
651 RADEON_GMC_BRUSH_NONE
|
653 RADEON_GMC_SRC_DATATYPE_COLOR
|
655 RADEON_DP_SRC_SOURCE_MEMORY
|
656 RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_WR_MSK_DIS
);
658 cmd
[3].u
= ((src_pitch
/ 64) << 22) | (src_offset
>> 10);
659 cmd
[4].u
= ((dst_pitch
/ 64) << 22) | (dst_offset
>> 10);
660 cmd
[5].u
= (srcx
<< 16) | srcy
;
661 cmd
[6].u
= (dstx
<< 16) | dsty
; /* dst */
662 cmd
[7].u
= (w
<< 16) | h
;
665 void r300EmitWait(r300ContextPtr rmesa
, GLuint flags
)
667 drm_r300_cmd_header_t
*cmd
;
669 assert(!(flags
& ~(R300_WAIT_2D
| R300_WAIT_3D
)));
671 cmd
= (drm_r300_cmd_header_t
*) r300AllocCmdBuf(rmesa
, 1, __FUNCTION__
);
673 cmd
[0].wait
.cmd_type
= R300_CMD_WAIT
;
674 cmd
[0].wait
.flags
= flags
;