ff25f3b88ae5db766d77d5296d6ba1d91115f3d1
[mesa.git] / src / gallium / drivers / r300 / r300_context.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
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 #include "draw/draw_context.h"
24
25 #include "util/u_memory.h"
26 #include "util/u_sampler.h"
27 #include "util/u_simple_list.h"
28 #include "util/u_upload_mgr.h"
29
30 #include "r300_cb.h"
31 #include "r300_context.h"
32 #include "r300_emit.h"
33 #include "r300_screen.h"
34 #include "r300_screen_buffer.h"
35 #include "r300_state_invariant.h"
36 #include "r300_winsys.h"
37
38 #include <inttypes.h>
39
40 static void r300_destroy_context(struct pipe_context* context)
41 {
42 struct r300_context* r300 = r300_context(context);
43 struct r300_query *query, *temp;
44 struct r300_atom *atom;
45
46 if (r300->texkill_sampler) {
47 pipe_sampler_view_reference(
48 (struct pipe_sampler_view**)&r300->texkill_sampler,
49 NULL);
50 }
51
52 util_blitter_destroy(r300->blitter);
53 draw_destroy(r300->draw);
54
55 /* Print stats, if enabled. */
56 if (SCREEN_DBG_ON(r300->screen, DBG_STATS)) {
57 fprintf(stderr, "r300: Stats for context %p:\n", r300);
58 fprintf(stderr, " : Flushes: %" PRIu64 "\n", r300->flush_counter);
59 foreach(atom, &r300->atom_list) {
60 fprintf(stderr, " : %s: %" PRIu64 " emits\n",
61 atom->name, atom->counter);
62 }
63 }
64
65 /* If there are any queries pending or not destroyed, remove them now. */
66 foreach_s(query, temp, &r300->query_list) {
67 remove_from_list(query);
68 FREE(query);
69 }
70
71 u_upload_destroy(r300->upload_vb);
72 u_upload_destroy(r300->upload_ib);
73
74 translate_cache_destroy(r300->tran.translate_cache);
75
76 FREE(r300->aa_state.state);
77 FREE(r300->blend_color_state.state);
78 FREE(r300->clip_state.state);
79 FREE(r300->fb_state.state);
80 FREE(r300->gpu_flush.state);
81 FREE(r300->rs_block_state.state);
82 FREE(r300->scissor_state.state);
83 FREE(r300->textures_state.state);
84 FREE(r300->vap_invariant_state.state);
85 FREE(r300->viewport_state.state);
86 FREE(r300->ztop_state.state);
87 FREE(r300->fs_constants.state);
88 FREE(r300->vs_constants.state);
89 if (!r300->screen->caps.has_tcl) {
90 FREE(r300->vertex_stream_state.state);
91 }
92 FREE(r300);
93 }
94
95 static void r300_flush_cb(void *data)
96 {
97 struct r300_context* const cs_context_copy = data;
98
99 cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL);
100 }
101
102 #define R300_INIT_ATOM(atomname, atomsize) \
103 r300->atomname.name = #atomname; \
104 r300->atomname.state = NULL; \
105 r300->atomname.size = atomsize; \
106 r300->atomname.emit = r300_emit_##atomname; \
107 r300->atomname.dirty = FALSE; \
108 insert_at_tail(&r300->atom_list, &r300->atomname);
109
110 static void r300_setup_atoms(struct r300_context* r300)
111 {
112 boolean is_r500 = r300->screen->caps.is_r500;
113 boolean has_tcl = r300->screen->caps.has_tcl;
114
115 /* Create the actual atom list.
116 *
117 * Each atom is examined and emitted in the order it appears here, which
118 * can affect performance and conformance if not handled with care.
119 *
120 * Some atoms never change size, others change every emit - those have
121 * the size of 0 here. */
122 make_empty_list(&r300->atom_list);
123 /* GB (unpipelined), RB3D (unpipelined), ZB (unpipelined), US, SC. */
124 R300_INIT_ATOM(gpu_flush, 9);
125 R300_INIT_ATOM(aa_state, 4);
126 R300_INIT_ATOM(fb_state, 0);
127 R300_INIT_ATOM(ztop_state, 2);
128 /* ZB, FG. */
129 R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6);
130 /* RB3D. */
131 R300_INIT_ATOM(blend_state, 8);
132 R300_INIT_ATOM(blend_color_state, is_r500 ? 3 : 2);
133 /* SC. */
134 R300_INIT_ATOM(scissor_state, 3);
135 /* GB, FG, GA, SU, SC, RB3D. */
136 R300_INIT_ATOM(invariant_state, 22);
137 /* VAP. */
138 R300_INIT_ATOM(viewport_state, 9);
139 R300_INIT_ATOM(pvs_flush, 2);
140 R300_INIT_ATOM(vap_invariant_state, 9);
141 R300_INIT_ATOM(vertex_stream_state, 0);
142 R300_INIT_ATOM(vs_state, 0);
143 R300_INIT_ATOM(vs_constants, 0);
144 R300_INIT_ATOM(clip_state, has_tcl ? 5 + (6 * 4) : 2);
145 /* VAP, RS, GA, GB. */
146 R300_INIT_ATOM(rs_block_state, 0);
147 R300_INIT_ATOM(rs_state, 0);
148 /* US. */
149 R300_INIT_ATOM(fs, 0);
150 R300_INIT_ATOM(fs_rc_constant_state, 0);
151 R300_INIT_ATOM(fs_constants, 0);
152 /* TX. */
153 R300_INIT_ATOM(texture_cache_inval, 2);
154 R300_INIT_ATOM(textures_state, 0);
155 /* ZB (unpipelined), SU. */
156 R300_INIT_ATOM(query_start, 4);
157
158 /* Replace emission functions for r500. */
159 if (is_r500) {
160 r300->fs.emit = r500_emit_fs;
161 r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state;
162 r300->fs_constants.emit = r500_emit_fs_constants;
163 }
164
165 /* Some non-CSO atoms need explicit space to store the state locally. */
166 r300->aa_state.state = CALLOC_STRUCT(r300_aa_state);
167 r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
168 r300->clip_state.state = CALLOC_STRUCT(r300_clip_state);
169 r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state);
170 r300->gpu_flush.state = CALLOC_STRUCT(pipe_framebuffer_state);
171 r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
172 r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
173 r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
174 r300->vap_invariant_state.state = CALLOC_STRUCT(r300_vap_invariant_state);
175 r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
176 r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
177 r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
178 r300->vs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
179 if (!r300->screen->caps.has_tcl) {
180 r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
181 }
182
183 /* Some non-CSO atoms don't use the state pointer. */
184 r300->invariant_state.allow_null_state = TRUE;
185 r300->fs_rc_constant_state.allow_null_state = TRUE;
186 r300->pvs_flush.allow_null_state = TRUE;
187 r300->query_start.allow_null_state = TRUE;
188 r300->texture_cache_inval.allow_null_state = TRUE;
189
190 /* Some states must be marked dirty here to properly set up
191 * hardware in the first command stream. */
192 r300->invariant_state.dirty = TRUE;
193 r300->pvs_flush.dirty = TRUE;
194 r300->vap_invariant_state.dirty = TRUE;
195 r300->texture_cache_inval.dirty = TRUE;
196 r300->textures_state.dirty = TRUE;
197 }
198
199 /* Not every state tracker calls every driver function before the first draw
200 * call and we must initialize the command buffers somehow. */
201 static void r300_init_states(struct pipe_context *pipe)
202 {
203 struct r300_context *r300 = r300_context(pipe);
204 struct pipe_blend_color bc = {{0}};
205 struct pipe_clip_state cs = {{{0}}};
206 struct pipe_scissor_state ss = {0};
207 struct r300_clip_state *clip =
208 (struct r300_clip_state*)r300->clip_state.state;
209 struct r300_gpu_flush *gpuflush =
210 (struct r300_gpu_flush*)r300->gpu_flush.state;
211 struct r300_vap_invariant_state *vap_invariant =
212 (struct r300_vap_invariant_state*)r300->vap_invariant_state.state;
213 CB_LOCALS;
214
215 pipe->set_blend_color(pipe, &bc);
216 pipe->set_scissor_state(pipe, &ss);
217
218 /* Initialize the clip state. */
219 if (r300_context(pipe)->screen->caps.has_tcl) {
220 pipe->set_clip_state(pipe, &cs);
221 } else {
222 BEGIN_CB(clip->cb, 2);
223 OUT_CB_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
224 END_CB;
225 }
226
227 /* Initialize the GPU flush. */
228 {
229 BEGIN_CB(gpuflush->cb_flush_clean, 6);
230
231 /* Flush and free renderbuffer caches. */
232 OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT,
233 R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
234 R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
235 OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT,
236 R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
237 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
238
239 /* Wait until the GPU is idle.
240 * This fixes random pixels sometimes appearing probably caused
241 * by incomplete rendering. */
242 OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
243 END_CB;
244 }
245
246 /* Initialize the VAP invariant state. */
247 {
248 BEGIN_CB(vap_invariant->cb, 9);
249 OUT_CB_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff);
250 OUT_CB_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
251 OUT_CB_32F(1.0);
252 OUT_CB_32F(1.0);
253 OUT_CB_32F(1.0);
254 OUT_CB_32F(1.0);
255 OUT_CB_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
256 END_CB;
257 }
258 }
259
260 struct pipe_context* r300_create_context(struct pipe_screen* screen,
261 void *priv)
262 {
263 struct r300_context* r300 = CALLOC_STRUCT(r300_context);
264 struct r300_screen* r300screen = r300_screen(screen);
265 struct r300_winsys_screen *rws = r300screen->rws;
266
267 if (!r300)
268 return NULL;
269
270 r300->rws = rws;
271 r300->screen = r300screen;
272
273 r300->context.winsys = (struct pipe_winsys*)rws;
274 r300->context.screen = screen;
275 r300->context.priv = priv;
276
277 r300->context.destroy = r300_destroy_context;
278
279 if (!r300screen->caps.has_tcl) {
280 /* Create a Draw. This is used for SW TCL. */
281 r300->draw = draw_create(&r300->context);
282 /* Enable our renderer. */
283 draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
284 /* Enable Draw's clipping. */
285 draw_set_driver_clipping(r300->draw, FALSE);
286 /* Disable converting points/lines to triangles. */
287 draw_wide_line_threshold(r300->draw, 10000000.f);
288 draw_wide_point_threshold(r300->draw, 10000000.f);
289 }
290
291 r300_setup_atoms(r300);
292
293 make_empty_list(&r300->query_list);
294
295 r300_init_blit_functions(r300);
296 r300_init_flush_functions(r300);
297 r300_init_query_functions(r300);
298 r300_init_render_functions(r300);
299 r300_init_state_functions(r300);
300 r300_init_resource_functions(r300);
301
302 rws->set_flush_cb(r300->rws, r300_flush_cb, r300);
303 r300->dirty_hw++;
304
305 r300->blitter = util_blitter_create(&r300->context);
306
307 r300->upload_ib = u_upload_create(&r300->context,
308 32 * 1024, 16,
309 PIPE_BIND_INDEX_BUFFER);
310
311 if (r300->upload_ib == NULL)
312 goto no_upload_ib;
313
314 r300->upload_vb = u_upload_create(&r300->context,
315 128 * 1024, 16,
316 PIPE_BIND_VERTEX_BUFFER);
317 if (r300->upload_vb == NULL)
318 goto no_upload_vb;
319
320 r300->tran.translate_cache = translate_cache_create();
321
322 r300_init_states(&r300->context);
323
324 /* The KIL opcode needs the first texture unit to be enabled
325 * on r3xx-r4xx. In order to calm down the CS checker, we bind this
326 * dummy texture there. */
327 if (!r300->screen->caps.is_r500) {
328 struct pipe_resource *tex;
329 struct pipe_resource rtempl = {{0}};
330 struct pipe_sampler_view vtempl = {{0}};
331
332 rtempl.target = PIPE_TEXTURE_2D;
333 rtempl.format = PIPE_FORMAT_I8_UNORM;
334 rtempl.bind = PIPE_BIND_SAMPLER_VIEW;
335 rtempl.width0 = 1;
336 rtempl.height0 = 1;
337 rtempl.depth0 = 1;
338 tex = screen->resource_create(screen, &rtempl);
339
340 u_sampler_view_default_template(&vtempl, tex, tex->format);
341
342 r300->texkill_sampler = (struct r300_sampler_view*)
343 r300->context.create_sampler_view(&r300->context, tex, &vtempl);
344
345 pipe_resource_reference(&tex, NULL);
346 }
347
348 return &r300->context;
349
350 no_upload_ib:
351 u_upload_destroy(r300->upload_ib);
352 no_upload_vb:
353 FREE(r300);
354 return NULL;
355 }
356
357 boolean r300_check_cs(struct r300_context *r300, unsigned size)
358 {
359 return size <= r300->rws->get_cs_free_dwords(r300->rws);
360 }
361
362 void r300_finish(struct r300_context *r300)
363 {
364 struct pipe_framebuffer_state *fb;
365 unsigned i;
366
367 /* This is a preliminary implementation of glFinish.
368 *
369 * The ideal implementation should use something like EmitIrqLocked and
370 * WaitIrq, or better, real fences.
371 */
372 if (r300->fb_state.state) {
373 fb = r300->fb_state.state;
374
375 for (i = 0; i < fb->nr_cbufs; i++) {
376 if (fb->cbufs[i]->texture) {
377 r300->rws->buffer_wait(r300->rws,
378 r300_texture(fb->cbufs[i]->texture)->buffer);
379 return;
380 }
381 }
382 if (fb->zsbuf && fb->zsbuf->texture) {
383 r300->rws->buffer_wait(r300->rws,
384 r300_texture(fb->zsbuf->texture)->buffer);
385 }
386 }
387 }