2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include "radeon_priv.h"
33 static int r600_state_pm4_resource(struct radeon_state
*state
);
34 static int r600_state_pm4_cb0(struct radeon_state
*state
);
35 static int r600_state_pm4_vgt(struct radeon_state
*state
);
36 static int r600_state_pm4_db(struct radeon_state
*state
);
37 static int r600_state_pm4_shader(struct radeon_state
*state
);
38 static int r600_state_pm4_draw(struct radeon_state
*state
);
39 static int r600_state_pm4_config(struct radeon_state
*state
);
40 static int r600_state_pm4_generic(struct radeon_state
*state
);
41 static int r700_state_pm4_config(struct radeon_state
*state
);
42 static int r700_state_pm4_cb0(struct radeon_state
*state
);
43 static int r700_state_pm4_db(struct radeon_state
*state
);
45 #include "r600_states.h"
48 * r600/r700 state functions
50 static int r600_state_pm4_bytecode(struct radeon_state
*state
, unsigned offset
, unsigned id
, unsigned nreg
)
52 const struct radeon_register
*regs
= state
->radeon
->type
[state
->type
].regs
;
57 fprintf(stderr
, "%s invalid register for state %d %d\n",
58 __func__
, state
->type
, id
);
61 if (offset
>= R600_CONFIG_REG_OFFSET
&& offset
< R600_CONFIG_REG_END
) {
62 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_CONFIG_REG
, nreg
);
63 state
->pm4
[state
->cpm4
++] = (offset
- R600_CONFIG_REG_OFFSET
) >> 2;
64 for (i
= 0; i
< nreg
; i
++) {
65 state
->pm4
[state
->cpm4
++] = state
->states
[id
+ i
];
67 for (i
= 0; i
< nreg
; i
++) {
68 if (regs
[id
+ i
].need_reloc
) {
69 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NOP
, 0);
70 r
= radeon_state_reloc(state
, state
->cpm4
, regs
[id
+ i
].bo_id
);
73 state
->pm4
[state
->cpm4
++] = state
->bo
[regs
[id
+ i
].bo_id
]->handle
;
78 if (offset
>= R600_CONTEXT_REG_OFFSET
&& offset
< R600_CONTEXT_REG_END
) {
79 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_CONTEXT_REG
, nreg
);
80 state
->pm4
[state
->cpm4
++] = (offset
- R600_CONTEXT_REG_OFFSET
) >> 2;
81 for (i
= 0; i
< nreg
; i
++) {
82 state
->pm4
[state
->cpm4
++] = state
->states
[id
+ i
];
84 for (i
= 0; i
< nreg
; i
++) {
85 if (regs
[id
+ i
].need_reloc
) {
86 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NOP
, 0);
87 r
= radeon_state_reloc(state
, state
->cpm4
, regs
[id
+ i
].bo_id
);
90 state
->pm4
[state
->cpm4
++] = state
->bo
[regs
[id
+ i
].bo_id
]->handle
;
95 if (offset
>= R600_ALU_CONST_OFFSET
&& offset
< R600_ALU_CONST_END
) {
96 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_ALU_CONST
, nreg
);
97 state
->pm4
[state
->cpm4
++] = (offset
- R600_ALU_CONST_OFFSET
) >> 2;
98 for (i
= 0; i
< nreg
; i
++) {
99 state
->pm4
[state
->cpm4
++] = state
->states
[id
+ i
];
103 if (offset
>= R600_SAMPLER_OFFSET
&& offset
< R600_SAMPLER_END
) {
104 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_SAMPLER
, nreg
);
105 state
->pm4
[state
->cpm4
++] = (offset
- R600_SAMPLER_OFFSET
) >> 2;
106 for (i
= 0; i
< nreg
; i
++) {
107 state
->pm4
[state
->cpm4
++] = state
->states
[id
+ i
];
111 fprintf(stderr
, "%s unsupported offset 0x%08X\n", __func__
, offset
);
115 static int r600_state_pm4_generic(struct radeon_state
*state
)
117 struct radeon
*radeon
= state
->radeon
;
118 unsigned i
, offset
, nreg
, type
, coffset
, loffset
, soffset
;
125 soffset
= (state
->id
- radeon
->type
[type
].id
) * radeon
->type
[type
].stride
;
126 offset
= loffset
= radeon
->type
[type
].regs
[0].offset
+ soffset
;
128 for (i
= 1, nreg
= 1; i
< state
->nstates
; i
++) {
129 coffset
= radeon
->type
[type
].regs
[i
].offset
+ soffset
;
130 if (coffset
== (loffset
+ 4)) {
134 r
= r600_state_pm4_bytecode(state
, offset
, start
, nreg
);
136 fprintf(stderr
, "%s invalid 0x%08X %d\n", __func__
, start
, nreg
);
139 offset
= loffset
= coffset
;
144 return r600_state_pm4_bytecode(state
, offset
, start
, nreg
);
147 static void r600_state_pm4_with_flush(struct radeon_state
*state
, u32 flags
)
149 unsigned i
, j
, add
, size
;
152 for (i
= 0; i
< state
->nbo
; i
++) {
153 for (j
= 0, add
= 1; j
< state
->nreloc
; j
++) {
154 if (state
->bo
[state
->reloc_bo_id
[j
]] == state
->bo
[i
]) {
160 state
->reloc_bo_id
[state
->nreloc
++] = i
;
163 for (i
= 0; i
< state
->nreloc
; i
++) {
164 size
= (state
->bo
[state
->reloc_bo_id
[i
]]->size
+ 255) >> 8;
165 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SURFACE_SYNC
, 3);
166 state
->pm4
[state
->cpm4
++] = flags
;
167 state
->pm4
[state
->cpm4
++] = size
;
168 state
->pm4
[state
->cpm4
++] = 0x00000000;
169 state
->pm4
[state
->cpm4
++] = 0x0000000A;
170 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NOP
, 0);
171 state
->reloc_pm4_id
[i
] = state
->cpm4
;
172 state
->pm4
[state
->cpm4
++] = state
->bo
[state
->reloc_bo_id
[i
]]->handle
;
176 static int r600_state_pm4_cb0(struct radeon_state
*state
)
180 r600_state_pm4_with_flush(state
, S_0085F0_CB_ACTION_ENA(1) |
181 S_0085F0_CB0_DEST_BASE_ENA(1));
182 r
= r600_state_pm4_generic(state
);
185 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SURFACE_BASE_UPDATE
, 0);
186 state
->pm4
[state
->cpm4
++] = 0x00000002;
190 static int r700_state_pm4_cb0(struct radeon_state
*state
)
194 r600_state_pm4_with_flush(state
, S_0085F0_CB_ACTION_ENA(1) |
195 S_0085F0_CB0_DEST_BASE_ENA(1));
196 r
= r600_state_pm4_generic(state
);
202 static int r600_state_pm4_db(struct radeon_state
*state
)
206 r600_state_pm4_with_flush(state
, S_0085F0_DB_ACTION_ENA(1) |
207 S_0085F0_DB_DEST_BASE_ENA(1));
208 r
= r600_state_pm4_generic(state
);
211 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SURFACE_BASE_UPDATE
, 0);
212 state
->pm4
[state
->cpm4
++] = 0x00000001;
216 static int r700_state_pm4_db(struct radeon_state
*state
)
220 r600_state_pm4_with_flush(state
, S_0085F0_DB_ACTION_ENA(1) |
221 S_0085F0_DB_DEST_BASE_ENA(1));
222 r
= r600_state_pm4_generic(state
);
228 static int r600_state_pm4_config(struct radeon_state
*state
)
230 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_START_3D_CMDBUF
, 0);
231 state
->pm4
[state
->cpm4
++] = 0x00000000;
232 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_CONTEXT_CONTROL
, 1);
233 state
->pm4
[state
->cpm4
++] = 0x80000000;
234 state
->pm4
[state
->cpm4
++] = 0x80000000;
235 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_EVENT_WRITE
, 0);
236 state
->pm4
[state
->cpm4
++] = 0x00000016;
237 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_CONFIG_REG
, 1);
238 state
->pm4
[state
->cpm4
++] = 0x00000010;
239 state
->pm4
[state
->cpm4
++] = 0x00028000;
240 return r600_state_pm4_generic(state
);
243 static int r700_state_pm4_config(struct radeon_state
*state
)
245 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_CONTEXT_CONTROL
, 1);
246 state
->pm4
[state
->cpm4
++] = 0x80000000;
247 state
->pm4
[state
->cpm4
++] = 0x80000000;
248 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_EVENT_WRITE
, 0);
249 state
->pm4
[state
->cpm4
++] = 0x00000016;
250 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_CONFIG_REG
, 1);
251 state
->pm4
[state
->cpm4
++] = 0x00000010;
252 state
->pm4
[state
->cpm4
++] = 0x00028000;
253 return r600_state_pm4_generic(state
);
256 static int r600_state_pm4_shader(struct radeon_state
*state
)
258 r600_state_pm4_with_flush(state
, S_0085F0_SH_ACTION_ENA(1));
259 return r600_state_pm4_generic(state
);
262 static int r600_state_pm4_vgt(struct radeon_state
*state
)
266 r
= r600_state_pm4_bytecode(state
, R_028400_VGT_MAX_VTX_INDX
, R600_VGT__VGT_MAX_VTX_INDX
, 1);
269 r
= r600_state_pm4_bytecode(state
, R_028404_VGT_MIN_VTX_INDX
, R600_VGT__VGT_MIN_VTX_INDX
, 1);
272 r
= r600_state_pm4_bytecode(state
, R_028408_VGT_INDX_OFFSET
, R600_VGT__VGT_INDX_OFFSET
, 1);
275 r
= r600_state_pm4_bytecode(state
, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX
, R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX
, 1);
278 r
= r600_state_pm4_bytecode(state
, R_008958_VGT_PRIMITIVE_TYPE
, R600_VGT__VGT_PRIMITIVE_TYPE
, 1);
281 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_INDEX_TYPE
, 0);
282 state
->pm4
[state
->cpm4
++] = state
->states
[R600_VGT__VGT_DMA_INDEX_TYPE
];
283 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NUM_INSTANCES
, 0);
284 state
->pm4
[state
->cpm4
++] = state
->states
[R600_VGT__VGT_DMA_NUM_INSTANCES
];
288 static int r600_state_pm4_draw(struct radeon_state
*state
)
294 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_DRAW_INDEX
, 3);
295 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_DMA_BASE
];
296 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_DMA_BASE_HI
];
297 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_NUM_INDICES
];
298 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_DRAW_INITIATOR
];
299 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NOP
, 0);
300 r
= radeon_state_reloc(state
, state
->cpm4
, 0);
303 state
->pm4
[state
->cpm4
++] = state
->bo
[0]->handle
;
304 } else if (state
->nimmd
) {
305 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_DRAW_INDEX_IMMD
, state
->nimmd
+ 1);
306 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_NUM_INDICES
];
307 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_DRAW_INITIATOR
];
308 for (i
= 0; i
< state
->nimmd
; i
++) {
309 state
->pm4
[state
->cpm4
++] = state
->immd
[i
];
312 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_DRAW_INDEX_AUTO
, 1);
313 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_NUM_INDICES
];
314 state
->pm4
[state
->cpm4
++] = state
->states
[R600_DRAW__VGT_DRAW_INITIATOR
];
316 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_EVENT_WRITE
, 0);
317 state
->pm4
[state
->cpm4
++] = 0x00000016;
321 static int r600_state_pm4_resource(struct radeon_state
*state
)
323 u32 flags
, type
, nbo
, offset
, soffset
;
326 soffset
= (state
->id
- state
->radeon
->type
[state
->type
].id
) * state
->radeon
->type
[state
->type
].stride
;
327 type
= G_038018_TYPE(state
->states
[6]);
330 flags
= S_0085F0_TC_ACTION_ENA(1);
334 flags
= S_0085F0_VC_ACTION_ENA(1);
340 if (state
->nbo
!= nbo
) {
341 fprintf(stderr
, "%s need %d bo got %d\n", __func__
, nbo
, state
->nbo
);
344 r600_state_pm4_with_flush(state
, flags
);
345 offset
= state
->radeon
->type
[state
->type
].regs
[0].offset
+ soffset
;
346 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_SET_RESOURCE
, 7);
347 state
->pm4
[state
->cpm4
++] = (offset
- R_038000_SQ_TEX_RESOURCE_WORD0_0
) >> 2;
348 state
->pm4
[state
->cpm4
++] = state
->states
[0];
349 state
->pm4
[state
->cpm4
++] = state
->states
[1];
350 state
->pm4
[state
->cpm4
++] = state
->states
[2];
351 state
->pm4
[state
->cpm4
++] = state
->states
[3];
352 state
->pm4
[state
->cpm4
++] = state
->states
[4];
353 state
->pm4
[state
->cpm4
++] = state
->states
[5];
354 state
->pm4
[state
->cpm4
++] = state
->states
[6];
355 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NOP
, 0);
356 r
= radeon_state_reloc(state
, state
->cpm4
, 0);
359 state
->pm4
[state
->cpm4
++] = state
->bo
[0]->handle
;
361 state
->pm4
[state
->cpm4
++] = PKT3(PKT3_NOP
, 0);
362 r
= radeon_state_reloc(state
, state
->cpm4
, 1);
365 state
->pm4
[state
->cpm4
++] = state
->bo
[1]->handle
;
370 int r600_init(struct radeon
*radeon
)
372 switch (radeon
->family
) {
381 radeon
->ntype
= R600_NTYPE
;
382 radeon
->nstate
= R600_NSTATE
;
383 radeon
->type
= R600_types
;
389 radeon
->ntype
= R600_NTYPE
;
390 radeon
->nstate
= R600_NSTATE
;
391 radeon
->type
= R700_types
;
394 fprintf(stderr
, "%s unknown or unsupported chipset 0x%04X\n",
395 __func__
, radeon
->device
);