Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Copyright 2010 Jerome Glisse 
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
 
27
#include "si_pipe.h"
28
 
29
/* initialize */
30
void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
31
			boolean count_draw_in)
32
{
33
	int i;
34
 
35
	/* The number of dwords we already used in the CS so far. */
36
	num_dw += ctx->b.rings.gfx.cs->cdw;
37
 
38
	if (count_draw_in) {
39
		for (i = 0; i < SI_NUM_ATOMS(ctx); i++) {
40
			if (ctx->atoms.array[i]->dirty) {
41
				num_dw += ctx->atoms.array[i]->num_dw;
42
			}
43
		}
44
 
45
		/* The number of dwords all the dirty states would take. */
46
		num_dw += si_pm4_dirty_dw(ctx);
47
 
48
		/* The upper-bound of how much a draw command would take. */
49
		num_dw += SI_MAX_DRAW_CS_DWORDS;
50
	}
51
 
52
	/* Count in queries_suspend. */
53
	num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
54
 
55
	/* Count in streamout_end at the end of CS. */
56
	if (ctx->b.streamout.begin_emitted) {
57
		num_dw += ctx->b.streamout.num_dw_for_end;
58
	}
59
 
60
	/* Count in render_condition(NULL) at the end of CS. */
61
	if (ctx->b.predicate_drawing) {
62
		num_dw += 3;
63
	}
64
 
65
	/* Count in framebuffer cache flushes at the end of CS. */
66
	num_dw += ctx->atoms.s.cache_flush->num_dw;
67
 
68
#if SI_TRACE_CS
69
	if (ctx->screen->b.trace_bo) {
70
		num_dw += SI_TRACE_CS_DWORDS;
71
	}
72
#endif
73
 
74
	/* Flush if there's not enough space. */
75
	if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
76
		ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
77
	}
78
}
79
 
80
void si_context_gfx_flush(void *context, unsigned flags,
81
			  struct pipe_fence_handle **fence)
82
{
83
	struct si_context *ctx = context;
84
	struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
85
 
86
	if (cs->cdw == ctx->b.initial_gfx_cs_size && !fence)
87
		return;
88
 
89
	ctx->b.rings.gfx.flushing = true;
90
 
91
	r600_preflush_suspend_features(&ctx->b);
92
 
93
	ctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_FRAMEBUFFER |
94
			SI_CONTEXT_INV_TC_L1 |
95
			SI_CONTEXT_INV_TC_L2 |
96
			/* this is probably not needed anymore */
97
			SI_CONTEXT_PS_PARTIAL_FLUSH;
98
	si_emit_cache_flush(&ctx->b, NULL);
99
 
100
	/* force to keep tiling flags */
101
	flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
102
 
103
	/* Flush the CS. */
104
	ctx->b.ws->cs_flush(cs, flags, fence, ctx->screen->b.cs_count++);
105
	ctx->b.rings.gfx.flushing = false;
106
 
107
#if SI_TRACE_CS
108
	if (ctx->screen->b.trace_bo) {
109
		struct si_screen *sscreen = ctx->screen;
110
		unsigned i;
111
 
112
		for (i = 0; i < 10; i++) {
113
			usleep(5);
114
			if (!ctx->b.ws->buffer_is_busy(sscreen->b.trace_bo->buf, RADEON_USAGE_READWRITE)) {
115
				break;
116
			}
117
		}
118
		if (i == 10) {
119
			fprintf(stderr, "timeout on cs lockup likely happen at cs %d dw %d\n",
120
				sscreen->b.trace_ptr[1], sscreen->b.trace_ptr[0]);
121
		} else {
122
			fprintf(stderr, "cs %d executed in %dms\n", sscreen->b.trace_ptr[1], i * 5);
123
		}
124
	}
125
#endif
126
 
127
	si_begin_new_cs(ctx);
128
}
129
 
130
void si_begin_new_cs(struct si_context *ctx)
131
{
132
	/* Flush read caches at the beginning of CS. */
133
	ctx->b.flags |= SI_CONTEXT_INV_TC_L1 |
134
			SI_CONTEXT_INV_TC_L2 |
135
			SI_CONTEXT_INV_KCACHE |
136
			SI_CONTEXT_INV_ICACHE;
137
 
138
	/* set all valid group as dirty so they get reemited on
139
	 * next draw command
140
	 */
141
	si_pm4_reset_emitted(ctx);
142
 
143
	/* The CS initialization should be emitted before everything else. */
144
	si_pm4_emit(ctx, ctx->init_config);
145
 
146
	ctx->clip_regs.dirty = true;
147
	ctx->framebuffer.atom.dirty = true;
148
	ctx->msaa_sample_locs.dirty = true;
149
	ctx->msaa_config.dirty = true;
150
	ctx->db_render_state.dirty = true;
151
	ctx->b.streamout.enable_atom.dirty = true;
152
	si_all_descriptors_begin_new_cs(ctx);
153
 
154
	r600_postflush_resume_features(&ctx->b);
155
 
156
	ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
157
	si_invalidate_draw_sh_constants(ctx);
158
	ctx->last_primitive_restart_en = -1;
159
	ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN;
160
	ctx->last_gs_out_prim = -1;
161
	ctx->last_prim = -1;
162
	ctx->last_multi_vgt_param = -1;
163
	ctx->last_rast_prim = -1;
164
	ctx->last_sc_line_stipple = ~0;
165
	ctx->emit_scratch_reloc = true;
166
}