Revert "r600g: simplify states"
[mesa.git] / src / gallium / winsys / r600 / drm / r600_state.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 *
23 * Authors:
24 * Jerome Glisse
25 */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include "radeon_priv.h"
31 #include "r600d.h"
32
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 r600_state_pm4_query_begin(struct radeon_state *state);
42 static int r600_state_pm4_query_end(struct radeon_state *state);
43 static int r700_state_pm4_config(struct radeon_state *state);
44 static int r700_state_pm4_cb0(struct radeon_state *state);
45 static int r700_state_pm4_db(struct radeon_state *state);
46
47 #include "r600_states.h"
48
49 /*
50 * r600/r700 state functions
51 */
52 static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, unsigned id, unsigned nreg)
53 {
54 const struct radeon_register *regs = state->radeon->type[state->type].regs;
55 unsigned i;
56 int r;
57
58 if (!offset) {
59 fprintf(stderr, "%s invalid register for state %d %d\n",
60 __func__, state->type, id);
61 return -EINVAL;
62 }
63 if (offset >= R600_CONFIG_REG_OFFSET && offset < R600_CONFIG_REG_END) {
64 state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, nreg);
65 state->pm4[state->cpm4++] = (offset - R600_CONFIG_REG_OFFSET) >> 2;
66 for (i = 0; i < nreg; i++) {
67 state->pm4[state->cpm4++] = state->states[id + i];
68 }
69 for (i = 0; i < nreg; i++) {
70 if (regs[id + i].need_reloc) {
71 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
72 r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id);
73 if (r)
74 return r;
75 state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
76 }
77 }
78 return 0;
79 }
80 if (offset >= R600_CONTEXT_REG_OFFSET && offset < R600_CONTEXT_REG_END) {
81 state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONTEXT_REG, nreg);
82 state->pm4[state->cpm4++] = (offset - R600_CONTEXT_REG_OFFSET) >> 2;
83 for (i = 0; i < nreg; i++) {
84 state->pm4[state->cpm4++] = state->states[id + i];
85 }
86 for (i = 0; i < nreg; i++) {
87 if (regs[id + i].need_reloc) {
88 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
89 r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id);
90 if (r)
91 return r;
92 state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
93 }
94 }
95 return 0;
96 }
97 if (offset >= R600_ALU_CONST_OFFSET && offset < R600_ALU_CONST_END) {
98 state->pm4[state->cpm4++] = PKT3(PKT3_SET_ALU_CONST, nreg);
99 state->pm4[state->cpm4++] = (offset - R600_ALU_CONST_OFFSET) >> 2;
100 for (i = 0; i < nreg; i++) {
101 state->pm4[state->cpm4++] = state->states[id + i];
102 }
103 return 0;
104 }
105 if (offset >= R600_SAMPLER_OFFSET && offset < R600_SAMPLER_END) {
106 state->pm4[state->cpm4++] = PKT3(PKT3_SET_SAMPLER, nreg);
107 state->pm4[state->cpm4++] = (offset - R600_SAMPLER_OFFSET) >> 2;
108 for (i = 0; i < nreg; i++) {
109 state->pm4[state->cpm4++] = state->states[id + i];
110 }
111 return 0;
112 }
113 fprintf(stderr, "%s unsupported offset 0x%08X\n", __func__, offset);
114 return -EINVAL;
115 }
116
117 static int r600_state_pm4_generic(struct radeon_state *state)
118 {
119 struct radeon *radeon = state->radeon;
120 unsigned i, offset, nreg, type, coffset, loffset, soffset;
121 unsigned start;
122 int r;
123
124 if (!state->nstates)
125 return 0;
126 type = state->type;
127 soffset = (state->id - radeon->type[type].id) * radeon->type[type].stride;
128 offset = loffset = radeon->type[type].regs[0].offset + soffset;
129 start = 0;
130 for (i = 1, nreg = 1; i < state->nstates; i++) {
131 coffset = radeon->type[type].regs[i].offset + soffset;
132 if (coffset == (loffset + 4)) {
133 nreg++;
134 loffset = coffset;
135 } else {
136 r = r600_state_pm4_bytecode(state, offset, start, nreg);
137 if (r) {
138 fprintf(stderr, "%s invalid 0x%08X %d\n", __func__, start, nreg);
139 return r;
140 }
141 offset = loffset = coffset;
142 nreg = 1;
143 start = i;
144 }
145 }
146 return r600_state_pm4_bytecode(state, offset, start, nreg);
147 }
148
149 static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags)
150 {
151 unsigned i, j, add, size;
152
153 state->nreloc = 0;
154 for (i = 0; i < state->nbo; i++) {
155 for (j = 0, add = 1; j < state->nreloc; j++) {
156 if (state->bo[state->reloc_bo_id[j]] == state->bo[i]) {
157 add = 0;
158 break;
159 }
160 }
161 if (add) {
162 state->reloc_bo_id[state->nreloc++] = i;
163 }
164 }
165 for (i = 0; i < state->nreloc; i++) {
166 size = (state->bo[state->reloc_bo_id[i]]->size + 255) >> 8;
167 state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_SYNC, 3);
168 state->pm4[state->cpm4++] = flags;
169 state->pm4[state->cpm4++] = size;
170 state->pm4[state->cpm4++] = 0x00000000;
171 state->pm4[state->cpm4++] = 0x0000000A;
172 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
173 state->reloc_pm4_id[i] = state->cpm4;
174 state->pm4[state->cpm4++] = state->bo[state->reloc_bo_id[i]]->handle;
175 }
176 }
177
178 static int r600_state_pm4_cb0(struct radeon_state *state)
179 {
180 int r;
181
182 r600_state_pm4_with_flush(state, S_0085F0_CB_ACTION_ENA(1) |
183 S_0085F0_CB0_DEST_BASE_ENA(1));
184 r = r600_state_pm4_generic(state);
185 if (r)
186 return r;
187 state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
188 state->pm4[state->cpm4++] = 0x00000002;
189 return 0;
190 }
191
192 static int r700_state_pm4_cb0(struct radeon_state *state)
193 {
194 int r;
195
196 r600_state_pm4_with_flush(state, S_0085F0_CB_ACTION_ENA(1) |
197 S_0085F0_CB0_DEST_BASE_ENA(1));
198 r = r600_state_pm4_generic(state);
199 if (r)
200 return r;
201 return 0;
202 }
203
204 static int r600_state_pm4_db(struct radeon_state *state)
205 {
206 int r;
207
208 r600_state_pm4_with_flush(state, S_0085F0_DB_ACTION_ENA(1) |
209 S_0085F0_DB_DEST_BASE_ENA(1));
210 r = r600_state_pm4_generic(state);
211 if (r)
212 return r;
213 state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
214 state->pm4[state->cpm4++] = 0x00000001;
215 return 0;
216 }
217
218 static int r700_state_pm4_db(struct radeon_state *state)
219 {
220 int r;
221
222 r600_state_pm4_with_flush(state, S_0085F0_DB_ACTION_ENA(1) |
223 S_0085F0_DB_DEST_BASE_ENA(1));
224 r = r600_state_pm4_generic(state);
225 if (r)
226 return r;
227 return 0;
228 }
229
230 static int r600_state_pm4_config(struct radeon_state *state)
231 {
232 state->pm4[state->cpm4++] = PKT3(PKT3_START_3D_CMDBUF, 0);
233 state->pm4[state->cpm4++] = 0x00000000;
234 state->pm4[state->cpm4++] = PKT3(PKT3_CONTEXT_CONTROL, 1);
235 state->pm4[state->cpm4++] = 0x80000000;
236 state->pm4[state->cpm4++] = 0x80000000;
237 state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
238 state->pm4[state->cpm4++] = EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT;
239 state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, 1);
240 state->pm4[state->cpm4++] = 0x00000010;
241 state->pm4[state->cpm4++] = 0x00028000;
242 return r600_state_pm4_generic(state);
243 }
244
245 static int r600_state_pm4_query_begin(struct radeon_state *state)
246 {
247 int r;
248
249 state->cpm4 = 0;
250 state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 2);
251 state->pm4[state->cpm4++] = EVENT_TYPE_ZPASS_DONE;
252 state->pm4[state->cpm4++] = state->states[0];
253 state->pm4[state->cpm4++] = 0x0;
254 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
255 r = radeon_state_reloc(state, state->cpm4, 0);
256 if (r)
257 return r;
258 state->pm4[state->cpm4++] = state->bo[0]->handle;
259 return 0;
260 }
261
262 static int r600_state_pm4_query_end(struct radeon_state *state)
263 {
264 int r;
265
266 state->cpm4 = 0;
267 state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 2);
268 state->pm4[state->cpm4++] = EVENT_TYPE_ZPASS_DONE;
269 state->pm4[state->cpm4++] = state->states[0];
270 state->pm4[state->cpm4++] = 0x0;
271 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
272 r = radeon_state_reloc(state, state->cpm4, 0);
273 if (r)
274 return r;
275 state->pm4[state->cpm4++] = state->bo[0]->handle;
276 return 0;
277 }
278
279 static int r700_state_pm4_config(struct radeon_state *state)
280 {
281 state->pm4[state->cpm4++] = PKT3(PKT3_CONTEXT_CONTROL, 1);
282 state->pm4[state->cpm4++] = 0x80000000;
283 state->pm4[state->cpm4++] = 0x80000000;
284 state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
285 state->pm4[state->cpm4++] = EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT;
286 state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, 1);
287 state->pm4[state->cpm4++] = 0x00000010;
288 state->pm4[state->cpm4++] = 0x00028000;
289 return r600_state_pm4_generic(state);
290 }
291
292 static int r600_state_pm4_shader(struct radeon_state *state)
293 {
294 r600_state_pm4_with_flush(state, S_0085F0_SH_ACTION_ENA(1));
295 return r600_state_pm4_generic(state);
296 }
297
298 static int r600_state_pm4_vgt(struct radeon_state *state)
299 {
300 int r;
301
302 r = r600_state_pm4_bytecode(state, R_028400_VGT_MAX_VTX_INDX, R600_VGT__VGT_MAX_VTX_INDX, 1);
303 if (r)
304 return r;
305 r = r600_state_pm4_bytecode(state, R_028404_VGT_MIN_VTX_INDX, R600_VGT__VGT_MIN_VTX_INDX, 1);
306 if (r)
307 return r;
308 r = r600_state_pm4_bytecode(state, R_028408_VGT_INDX_OFFSET, R600_VGT__VGT_INDX_OFFSET, 1);
309 if (r)
310 return r;
311 r = r600_state_pm4_bytecode(state, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX, 1);
312 if (r)
313 return r;
314 r = r600_state_pm4_bytecode(state, R_008958_VGT_PRIMITIVE_TYPE, R600_VGT__VGT_PRIMITIVE_TYPE, 1);
315 if (r)
316 return r;
317 state->pm4[state->cpm4++] = PKT3(PKT3_INDEX_TYPE, 0);
318 state->pm4[state->cpm4++] = state->states[R600_VGT__VGT_DMA_INDEX_TYPE];
319 state->pm4[state->cpm4++] = PKT3(PKT3_NUM_INSTANCES, 0);
320 state->pm4[state->cpm4++] = state->states[R600_VGT__VGT_DMA_NUM_INSTANCES];
321 return 0;
322 }
323
324 static int r600_state_pm4_draw(struct radeon_state *state)
325 {
326 unsigned i;
327 int r;
328
329 if (state->nbo) {
330 state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX, 3);
331 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DMA_BASE];
332 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DMA_BASE_HI];
333 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
334 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
335 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
336 r = radeon_state_reloc(state, state->cpm4, 0);
337 if (r)
338 return r;
339 state->pm4[state->cpm4++] = state->bo[0]->handle;
340 } else if (state->nimmd) {
341 state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_IMMD, state->nimmd + 1);
342 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
343 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
344 for (i = 0; i < state->nimmd; i++) {
345 state->pm4[state->cpm4++] = state->immd[i];
346 }
347 } else {
348 state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1);
349 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
350 state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
351 }
352 state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
353 state->pm4[state->cpm4++] = EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT;
354 return 0;
355 }
356
357 static int r600_state_pm4_resource(struct radeon_state *state)
358 {
359 u32 flags, type, nbo, offset, soffset;
360 int r;
361
362 soffset = (state->id - state->radeon->type[state->type].id) * state->radeon->type[state->type].stride;
363 type = G_038018_TYPE(state->states[6]);
364 switch (type) {
365 case 2:
366 flags = S_0085F0_TC_ACTION_ENA(1);
367 nbo = 2;
368 break;
369 case 3:
370 flags = S_0085F0_VC_ACTION_ENA(1);
371 nbo = 1;
372 break;
373 default:
374 return 0;
375 }
376 if (state->nbo != nbo) {
377 fprintf(stderr, "%s need %d bo got %d\n", __func__, nbo, state->nbo);
378 return -EINVAL;
379 }
380 r600_state_pm4_with_flush(state, flags);
381 offset = state->radeon->type[state->type].regs[0].offset + soffset;
382 state->pm4[state->cpm4++] = PKT3(PKT3_SET_RESOURCE, 7);
383 state->pm4[state->cpm4++] = (offset - R_038000_SQ_TEX_RESOURCE_WORD0_0) >> 2;
384 state->pm4[state->cpm4++] = state->states[0];
385 state->pm4[state->cpm4++] = state->states[1];
386 state->pm4[state->cpm4++] = state->states[2];
387 state->pm4[state->cpm4++] = state->states[3];
388 state->pm4[state->cpm4++] = state->states[4];
389 state->pm4[state->cpm4++] = state->states[5];
390 state->pm4[state->cpm4++] = state->states[6];
391 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
392 r = radeon_state_reloc(state, state->cpm4, 0);
393 if (r)
394 return r;
395 state->pm4[state->cpm4++] = state->bo[0]->handle;
396 if (type == 2) {
397 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
398 r = radeon_state_reloc(state, state->cpm4, 1);
399 if (r)
400 return r;
401 state->pm4[state->cpm4++] = state->bo[1]->handle;
402 }
403 return 0;
404 }
405
406 int r600_init(struct radeon *radeon)
407 {
408 switch (radeon->family) {
409 case CHIP_R600:
410 case CHIP_RV610:
411 case CHIP_RV630:
412 case CHIP_RV670:
413 case CHIP_RV620:
414 case CHIP_RV635:
415 case CHIP_RS780:
416 case CHIP_RS880:
417 radeon->ntype = R600_NTYPE;
418 radeon->nstate = R600_NSTATE;
419 radeon->type = R600_types;
420 break;
421 case CHIP_RV770:
422 case CHIP_RV730:
423 case CHIP_RV710:
424 case CHIP_RV740:
425 radeon->ntype = R600_NTYPE;
426 radeon->nstate = R600_NSTATE;
427 radeon->type = R700_types;
428 break;
429 default:
430 fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
431 __func__, radeon->device);
432 return -EINVAL;
433 }
434 return 0;
435 }