freedreno_context.h revision 848b8605
1/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3/*
4 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 *    Rob Clark <robclark@freedesktop.org>
27 */
28
29#ifndef FREEDRENO_CONTEXT_H_
30#define FREEDRENO_CONTEXT_H_
31
32#include "draw/draw_context.h"
33#include "pipe/p_context.h"
34#include "indices/u_primconvert.h"
35#include "util/u_blitter.h"
36#include "util/u_double_list.h"
37#include "util/u_slab.h"
38#include "util/u_string.h"
39
40#include "freedreno_screen.h"
41#include "freedreno_gmem.h"
42#include "freedreno_util.h"
43
44struct fd_vertex_stateobj;
45
46struct fd_texture_stateobj {
47	struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS];
48	unsigned num_textures;
49	struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
50	unsigned num_samplers;
51	unsigned dirty_samplers;
52};
53
54struct fd_program_stateobj {
55	void *vp, *fp;
56	enum {
57		FD_SHADER_DIRTY_VP = (1 << 0),
58		FD_SHADER_DIRTY_FP = (1 << 1),
59	} dirty;
60	uint8_t num_exports;
61	/* Indexed by semantic name or TGSI_SEMANTIC_COUNT + semantic index
62	 * for TGSI_SEMANTIC_GENERIC.  Special vs exports (position and point-
63	 * size) are not included in this
64	 */
65	uint8_t export_linkage[63];
66};
67
68struct fd_constbuf_stateobj {
69	struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS];
70	uint32_t enabled_mask;
71	uint32_t dirty_mask;
72};
73
74struct fd_vertexbuf_stateobj {
75	struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
76	unsigned count;
77	uint32_t enabled_mask;
78	uint32_t dirty_mask;
79};
80
81struct fd_vertex_stateobj {
82	struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
83	unsigned num_elements;
84};
85
86/* group together the vertex and vertexbuf state.. for ease of passing
87 * around, and because various internal operations (gmem<->mem, etc)
88 * need their own vertex state:
89 */
90struct fd_vertex_state {
91	struct fd_vertex_stateobj *vtx;
92	struct fd_vertexbuf_stateobj vertexbuf;
93};
94
95/* Bitmask of stages in rendering that a particular query query is
96 * active.  Queries will be automatically started/stopped (generating
97 * additional fd_hw_sample_period's) on entrance/exit from stages that
98 * are applicable to the query.
99 *
100 * NOTE: set the stage to NULL at end of IB to ensure no query is still
101 * active.  Things aren't going to work out the way you want if a query
102 * is active across IB's (or between tile IB and draw IB)
103 */
104enum fd_render_stage {
105	FD_STAGE_NULL     = 0x00,
106	FD_STAGE_DRAW     = 0x01,
107	FD_STAGE_CLEAR    = 0x02,
108	/* TODO before queries which include MEM2GMEM or GMEM2MEM will
109	 * work we will need to call fd_hw_query_prepare() from somewhere
110	 * appropriate so that queries in the tiling IB get backed with
111	 * memory to write results to.
112	 */
113	FD_STAGE_MEM2GMEM = 0x04,
114	FD_STAGE_GMEM2MEM = 0x08,
115	/* used for driver internal draws (ie. util_blitter_blit()): */
116	FD_STAGE_BLIT     = 0x10,
117};
118
119#define MAX_HW_SAMPLE_PROVIDERS 4
120struct fd_hw_sample_provider;
121struct fd_hw_sample;
122
123struct fd_context {
124	struct pipe_context base;
125
126	struct fd_device *dev;
127	struct fd_screen *screen;
128
129	struct blitter_context *blitter;
130	struct primconvert_context *primconvert;
131
132	/* slab for pipe_transfer allocations: */
133	struct util_slab_mempool transfer_pool;
134
135	/* slabs for fd_hw_sample and fd_hw_sample_period allocations: */
136	struct util_slab_mempool sample_pool;
137	struct util_slab_mempool sample_period_pool;
138
139	/* next sample offset.. incremented for each sample in the batch/
140	 * submit, reset to zero on next submit.
141	 */
142	uint32_t next_sample_offset;
143
144	/* sample-providers for hw queries: */
145	const struct fd_hw_sample_provider *sample_providers[MAX_HW_SAMPLE_PROVIDERS];
146
147	/* cached samples (in case multiple queries need to reference
148	 * the same sample snapshot)
149	 */
150	struct fd_hw_sample *sample_cache[MAX_HW_SAMPLE_PROVIDERS];
151
152	/* tracking for current stage, to know when to start/stop
153	 * any active queries:
154	 */
155	enum fd_render_stage stage;
156
157	/* list of active queries: */
158	struct list_head active_queries;
159
160	/* list of queries that are not active, but were active in the
161	 * current submit:
162	 */
163	struct list_head current_queries;
164
165	/* current query result bo and tile stride: */
166	struct fd_bo *query_bo;
167	uint32_t query_tile_stride;
168
169	/* table with PIPE_PRIM_MAX entries mapping PIPE_PRIM_x to
170	 * DI_PT_x value to use for draw initiator.  There are some
171	 * slight differences between generation:
172	 */
173	const uint8_t *primtypes;
174	uint32_t primtype_mask;
175
176	/* shaders used by clear, and gmem->mem blits: */
177	struct fd_program_stateobj solid_prog; // TODO move to screen?
178
179	/* shaders used by mem->gmem blits: */
180	struct fd_program_stateobj blit_prog; // TODO move to screen?
181
182	/* do we need to mem2gmem before rendering.  We don't, if for example,
183	 * there was a glClear() that invalidated the entire previous buffer
184	 * contents.  Keep track of which buffer(s) are cleared, or needs
185	 * restore.  Masks of PIPE_CLEAR_*
186	 *
187	 * The 'cleared' bits will be set for buffers which are *entirely*
188	 * cleared, and 'partial_cleared' bits will be set if you must
189	 * check cleared_scissor.
190	 */
191	enum {
192		/* align bitmask values w/ PIPE_CLEAR_*.. since that is convenient.. */
193		FD_BUFFER_COLOR   = PIPE_CLEAR_COLOR0,
194		FD_BUFFER_DEPTH   = PIPE_CLEAR_DEPTH,
195		FD_BUFFER_STENCIL = PIPE_CLEAR_STENCIL,
196		FD_BUFFER_ALL     = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
197	} cleared, partial_cleared, restore, resolve;
198
199	bool needs_flush;
200
201	/* To decide whether to render to system memory, keep track of the
202	 * number of draws, and whether any of them require multisample,
203	 * depth_test (or depth write), stencil_test, blending, and
204	 * color_logic_Op (since those functions are disabled when by-
205	 * passing GMEM.
206	 */
207	enum {
208		FD_GMEM_CLEARS_DEPTH_STENCIL = 0x01,
209		FD_GMEM_DEPTH_ENABLED        = 0x02,
210		FD_GMEM_STENCIL_ENABLED      = 0x04,
211
212		FD_GMEM_MSAA_ENABLED         = 0x08,
213		FD_GMEM_BLEND_ENABLED        = 0x10,
214		FD_GMEM_LOGICOP_ENABLED      = 0x20,
215	} gmem_reason;
216	unsigned num_draws;   /* number of draws in current batch */
217
218	/* Stats/counters:
219	 */
220	struct {
221		uint64_t prims_emitted;
222		uint64_t draw_calls;
223		uint64_t batch_total, batch_sysmem, batch_gmem, batch_restore;
224	} stats;
225
226	/* we can't really sanely deal with wraparound point in ringbuffer
227	 * and because of the way tiling works we can't really flush at
228	 * arbitrary points (without a big performance hit).  When we get
229	 * too close to the end of the current ringbuffer, cycle to the next
230	 * one (and wait for pending rendering from next rb to complete).
231	 * We want the # of ringbuffers to be high enough that we don't
232	 * normally have to wait before resetting to the start of the next
233	 * rb.
234	 */
235	struct fd_ringbuffer *rings[8];
236	unsigned rings_idx;
237
238	/* NOTE: currently using a single ringbuffer for both draw and
239	 * tiling commands, we need to make sure we need to leave enough
240	 * room at the end to append the tiling commands when we flush.
241	 * 0x7000 dwords should be a couple times more than we ever need
242	 * so should be a nice conservative threshold.
243	 */
244#define FD_TILING_COMMANDS_DWORDS 0x7000
245
246	/* normal draw/clear cmds: */
247	struct fd_ringbuffer *ring;
248	struct fd_ringmarker *draw_start, *draw_end;
249
250	/* binning pass draw/clear cmds: */
251	struct fd_ringbuffer *binning_ring;
252	struct fd_ringmarker *binning_start, *binning_end;
253
254	/* Keep track if WAIT_FOR_IDLE is needed for registers we need
255	 * to update via RMW:
256	 */
257	bool needs_wfi;
258
259	/* Do we need to re-emit RB_FRAME_BUFFER_DIMENSION?  At least on a3xx
260	 * it is not a banked context register, so it needs a WFI to update.
261	 * Keep track if it has actually changed, to avoid unneeded WFI.
262	 * */
263	bool needs_rb_fbd;
264
265	/* Keep track of DRAW initiators that need to be patched up depending
266	 * on whether we using binning or not:
267	 */
268	struct util_dynarray draw_patches;
269
270	struct pipe_scissor_state scissor;
271
272	/* we don't have a disable/enable bit for scissor, so instead we keep
273	 * a disabled-scissor state which matches the entire bound framebuffer
274	 * and use that when scissor is not enabled.
275	 */
276	struct pipe_scissor_state disabled_scissor;
277
278	/* Track the maximal bounds of the scissor of all the draws within a
279	 * batch.  Used at the tile rendering step (fd_gmem_render_tiles(),
280	 * mem2gmem/gmem2mem) to avoid needlessly moving data in/out of gmem.
281	 */
282	struct pipe_scissor_state max_scissor;
283
284	/* Track the cleared scissor for color/depth/stencil, so we know
285	 * which, if any, tiles need to be restored (mem2gmem).  Only valid
286	 * if the corresponding bit in ctx->cleared is set.
287	 */
288	struct {
289		struct pipe_scissor_state color, depth, stencil;
290	} cleared_scissor;
291
292	/* Current gmem/tiling configuration.. gets updated on render_tiles()
293	 * if out of date with current maximal-scissor/cpp:
294	 */
295	struct fd_gmem_stateobj gmem;
296	struct fd_vsc_pipe      pipe[8];
297	struct fd_tile          tile[64];
298
299	/* which state objects need to be re-emit'd: */
300	enum {
301		FD_DIRTY_BLEND       = (1 <<  0),
302		FD_DIRTY_RASTERIZER  = (1 <<  1),
303		FD_DIRTY_ZSA         = (1 <<  2),
304		FD_DIRTY_FRAGTEX     = (1 <<  3),
305		FD_DIRTY_VERTTEX     = (1 <<  4),
306		FD_DIRTY_TEXSTATE    = (1 <<  5),
307		FD_DIRTY_PROG        = (1 <<  6),
308		FD_DIRTY_BLEND_COLOR = (1 <<  7),
309		FD_DIRTY_STENCIL_REF = (1 <<  8),
310		FD_DIRTY_SAMPLE_MASK = (1 <<  9),
311		FD_DIRTY_FRAMEBUFFER = (1 << 10),
312		FD_DIRTY_STIPPLE     = (1 << 11),
313		FD_DIRTY_VIEWPORT    = (1 << 12),
314		FD_DIRTY_CONSTBUF    = (1 << 13),
315		FD_DIRTY_VTXSTATE    = (1 << 14),
316		FD_DIRTY_VTXBUF      = (1 << 15),
317		FD_DIRTY_INDEXBUF    = (1 << 16),
318		FD_DIRTY_SCISSOR     = (1 << 17),
319	} dirty;
320
321	struct pipe_blend_state *blend;
322	struct pipe_rasterizer_state *rasterizer;
323	struct pipe_depth_stencil_alpha_state *zsa;
324
325	struct fd_texture_stateobj verttex, fragtex;
326
327	struct fd_program_stateobj prog;
328
329	struct fd_vertex_state vtx;
330
331	struct pipe_blend_color blend_color;
332	struct pipe_stencil_ref stencil_ref;
333	unsigned sample_mask;
334	struct pipe_framebuffer_state framebuffer;
335	struct pipe_poly_stipple stipple;
336	struct pipe_viewport_state viewport;
337	struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
338	struct pipe_index_buffer indexbuf;
339
340	/* GMEM/tile handling fxns: */
341	void (*emit_tile_init)(struct fd_context *ctx);
342	void (*emit_tile_prep)(struct fd_context *ctx, struct fd_tile *tile);
343	void (*emit_tile_mem2gmem)(struct fd_context *ctx, struct fd_tile *tile);
344	void (*emit_tile_renderprep)(struct fd_context *ctx, struct fd_tile *tile);
345	void (*emit_tile_gmem2mem)(struct fd_context *ctx, struct fd_tile *tile);
346
347	/* optional, for GMEM bypass: */
348	void (*emit_sysmem_prep)(struct fd_context *ctx);
349
350	/* draw: */
351	void (*draw)(struct fd_context *pctx, const struct pipe_draw_info *info);
352	void (*clear)(struct fd_context *ctx, unsigned buffers,
353			const union pipe_color_union *color, double depth, unsigned stencil);
354};
355
356static INLINE struct fd_context *
357fd_context(struct pipe_context *pctx)
358{
359	return (struct fd_context *)pctx;
360}
361
362static INLINE struct pipe_scissor_state *
363fd_context_get_scissor(struct fd_context *ctx)
364{
365	if (ctx->rasterizer && ctx->rasterizer->scissor)
366		return &ctx->scissor;
367	return &ctx->disabled_scissor;
368}
369
370static INLINE bool
371fd_supported_prim(struct fd_context *ctx, unsigned prim)
372{
373	return (1 << prim) & ctx->primtype_mask;
374}
375
376static INLINE void
377fd_reset_wfi(struct fd_context *ctx)
378{
379	ctx->needs_wfi = true;
380}
381
382/* emit a WAIT_FOR_IDLE only if needed, ie. if there has not already
383 * been one since last draw:
384 */
385static inline void
386fd_wfi(struct fd_context *ctx, struct fd_ringbuffer *ring)
387{
388	if (ctx->needs_wfi) {
389		OUT_WFI(ring);
390		ctx->needs_wfi = false;
391	}
392}
393
394/* emit a CP_EVENT_WRITE:
395 */
396static inline void
397fd_event_write(struct fd_context *ctx, struct fd_ringbuffer *ring,
398		enum vgt_event_type evt)
399{
400	OUT_PKT3(ring, CP_EVENT_WRITE, 1);
401	OUT_RING(ring, evt);
402	fd_reset_wfi(ctx);
403}
404
405struct pipe_context * fd_context_init(struct fd_context *ctx,
406		struct pipe_screen *pscreen, const uint8_t *primtypes,
407		void *priv);
408
409void fd_context_render(struct pipe_context *pctx);
410
411void fd_context_destroy(struct pipe_context *pctx);
412
413#endif /* FREEDRENO_CONTEXT_H_ */
414