Merge remote branch 'origin/master' into nv50-compiler
[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 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);
44
45 #include "r600_states.h"
46
47 /*
48 * r600/r700 state functions
49 */
50 static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, unsigned id, unsigned nreg)
51 {
52 const struct radeon_register *regs = state->radeon->type[state->type].regs;
53 unsigned i;
54 int r;
55
56 if (!offset) {
57 fprintf(stderr, "%s invalid register for state %d %d\n",
58 __func__, state->type, id);
59 return -EINVAL;
60 }
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];
66 }
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);
71 if (r)
72 return r;
73 state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
74 }
75 }
76 return 0;
77 }
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];
83 }
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);
88 if (r)
89 return r;
90 state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
91 }
92 }
93 return 0;
94 }
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];
100 }
101 return 0;
102 }
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];
108 }
109 return 0;
110 }
111 fprintf(stderr, "%s unsupported offset 0x%08X\n", __func__, offset);
112 return -EINVAL;
113 }
114
115 static int r600_state_pm4_generic(struct radeon_state *state)
116 {
117 struct radeon *radeon = state->radeon;
118 unsigned i, offset, nreg, type, coffset, loffset, soffset;
119 unsigned start;
120 int r;
121
122 if (!state->nstates)
123 return 0;
124 type = state->type;
125 soffset = (state->id - radeon->type[type].id) * radeon->type[type].stride;
126 offset = loffset = radeon->type[type].regs[0].offset + soffset;
127 start = 0;
128 for (i = 1, nreg = 1; i < state->nstates; i++) {
129 coffset = radeon->type[type].regs[i].offset + soffset;
130 if (coffset == (loffset + 4)) {
131 nreg++;
132 loffset = coffset;
133 } else {
134 r = r600_state_pm4_bytecode(state, offset, start, nreg);
135 if (r) {
136 fprintf(stderr, "%s invalid 0x%08X %d\n", __func__, start, nreg);
137 return r;
138 }
139 offset = loffset = coffset;
140 nreg = 1;
141 start = i;
142 }
143 }
144 return r600_state_pm4_bytecode(state, offset, start, nreg);
145 }
146
147 static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags)
148 {
149 unsigned i, j, add, size;
150
151 state->nreloc = 0;
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]) {
155 add = 0;
156 break;
157 }
158 }
159 if (add) {
160 state->reloc_bo_id[state->nreloc++] = i;
161 }
162 }
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;
173 }
174 }
175
176 static int r600_state_pm4_cb0(struct radeon_state *state)
177 {
178 int r;
179
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);
183 if (r)
184 return r;
185 state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
186 state->pm4[state->cpm4++] = 0x00000002;
187 return 0;
188 }
189
190 static int r700_state_pm4_cb0(struct radeon_state *state)
191 {
192 int r;
193
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);
197 if (r)
198 return r;
199 return 0;
200 }
201
202 static int r600_state_pm4_db(struct radeon_state *state)
203 {
204 int r;
205
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);
209 if (r)
210 return r;
211 state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
212 state->pm4[state->cpm4++] = 0x00000001;
213 return 0;
214 }
215
216 static int r700_state_pm4_db(struct radeon_state *state)
217 {
218 int r;
219
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);
223 if (r)
224 return r;
225 return 0;
226 }
227
228 static int r600_state_pm4_config(struct radeon_state *state)
229 {
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);
241 }
242
243 static int r700_state_pm4_config(struct radeon_state *state)
244 {
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);
254 }
255
256 static int r600_state_pm4_shader(struct radeon_state *state)
257 {
258 r600_state_pm4_with_flush(state, S_0085F0_SH_ACTION_ENA(1));
259 return r600_state_pm4_generic(state);
260 }
261
262 static int r600_state_pm4_vgt(struct radeon_state *state)
263 {
264 int r;
265
266 r = r600_state_pm4_bytecode(state, R_028400_VGT_MAX_VTX_INDX, R600_VGT__VGT_MAX_VTX_INDX, 1);
267 if (r)
268 return r;
269 r = r600_state_pm4_bytecode(state, R_028404_VGT_MIN_VTX_INDX, R600_VGT__VGT_MIN_VTX_INDX, 1);
270 if (r)
271 return r;
272 r = r600_state_pm4_bytecode(state, R_028408_VGT_INDX_OFFSET, R600_VGT__VGT_INDX_OFFSET, 1);
273 if (r)
274 return r;
275 r = r600_state_pm4_bytecode(state, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX, 1);
276 if (r)
277 return r;
278 r = r600_state_pm4_bytecode(state, R_008958_VGT_PRIMITIVE_TYPE, R600_VGT__VGT_PRIMITIVE_TYPE, 1);
279 if (r)
280 return r;
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];
285 return 0;
286 }
287
288 static int r600_state_pm4_draw(struct radeon_state *state)
289 {
290 unsigned i;
291 int r;
292
293 if (state->nbo) {
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);
301 if (r)
302 return r;
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];
310 }
311 } else {
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];
315 }
316 state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
317 state->pm4[state->cpm4++] = 0x00000016;
318 return 0;
319 }
320
321 static int r600_state_pm4_resource(struct radeon_state *state)
322 {
323 u32 flags, type, nbo, offset, soffset;
324 int r;
325
326 soffset = (state->id - state->radeon->type[state->type].id) * state->radeon->type[state->type].stride;
327 type = G_038018_TYPE(state->states[6]);
328 switch (type) {
329 case 2:
330 flags = S_0085F0_TC_ACTION_ENA(1);
331 nbo = 2;
332 break;
333 case 3:
334 flags = S_0085F0_VC_ACTION_ENA(1);
335 nbo = 1;
336 break;
337 default:
338 return 0;
339 }
340 if (state->nbo != nbo) {
341 fprintf(stderr, "%s need %d bo got %d\n", __func__, nbo, state->nbo);
342 return -EINVAL;
343 }
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);
357 if (r)
358 return r;
359 state->pm4[state->cpm4++] = state->bo[0]->handle;
360 if (type == 2) {
361 state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
362 r = radeon_state_reloc(state, state->cpm4, 1);
363 if (r)
364 return r;
365 state->pm4[state->cpm4++] = state->bo[1]->handle;
366 }
367 return 0;
368 }
369
370 int r600_init(struct radeon *radeon)
371 {
372 switch (radeon->family) {
373 case CHIP_R600:
374 case CHIP_RV610:
375 case CHIP_RV630:
376 case CHIP_RV670:
377 case CHIP_RV620:
378 case CHIP_RV635:
379 case CHIP_RS780:
380 case CHIP_RS880:
381 radeon->ntype = R600_NTYPE;
382 radeon->nstate = R600_NSTATE;
383 radeon->type = R600_types;
384 break;
385 case CHIP_RV770:
386 case CHIP_RV730:
387 case CHIP_RV710:
388 case CHIP_RV740:
389 radeon->ntype = R600_NTYPE;
390 radeon->nstate = R600_NSTATE;
391 radeon->type = R700_types;
392 break;
393 default:
394 fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
395 __func__, radeon->device);
396 return -EINVAL;
397 }
398 return 0;
399 }