1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci * Authors:
24bf215546Sopenharmony_ci *    Rob Clark <robclark@freedesktop.org>
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#ifndef FREEDRENO_CONTEXT_H_
28bf215546Sopenharmony_ci#define FREEDRENO_CONTEXT_H_
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "pipe/p_context.h"
31bf215546Sopenharmony_ci#include "util/libsync.h"
32bf215546Sopenharmony_ci#include "util/list.h"
33bf215546Sopenharmony_ci#include "util/slab.h"
34bf215546Sopenharmony_ci#include "util/u_blitter.h"
35bf215546Sopenharmony_ci#include "util/u_string.h"
36bf215546Sopenharmony_ci#include "util/u_threaded_context.h"
37bf215546Sopenharmony_ci#include "util/perf/u_trace.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci#include "freedreno_autotune.h"
40bf215546Sopenharmony_ci#include "freedreno_gmem.h"
41bf215546Sopenharmony_ci#include "freedreno_perfetto.h"
42bf215546Sopenharmony_ci#include "freedreno_screen.h"
43bf215546Sopenharmony_ci#include "freedreno_util.h"
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci#ifdef __cplusplus
46bf215546Sopenharmony_ciextern "C" {
47bf215546Sopenharmony_ci#endif
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci#define BORDER_COLOR_UPLOAD_SIZE (2 * PIPE_MAX_SAMPLERS * BORDERCOLOR_SIZE)
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_cistruct fd_vertex_stateobj;
52bf215546Sopenharmony_cistruct fd_batch;
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_cistruct fd_texture_stateobj {
55bf215546Sopenharmony_ci   struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS];
56bf215546Sopenharmony_ci   unsigned num_textures;
57bf215546Sopenharmony_ci   unsigned valid_textures;
58bf215546Sopenharmony_ci   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
59bf215546Sopenharmony_ci   unsigned num_samplers;
60bf215546Sopenharmony_ci   unsigned valid_samplers;
61bf215546Sopenharmony_ci};
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_cistruct fd_program_stateobj {
64bf215546Sopenharmony_ci   void *vs, *hs, *ds, *gs, *fs;
65bf215546Sopenharmony_ci};
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_cistruct fd_constbuf_stateobj {
68bf215546Sopenharmony_ci   struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS];
69bf215546Sopenharmony_ci   uint32_t enabled_mask;
70bf215546Sopenharmony_ci};
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_cistruct fd_shaderbuf_stateobj {
73bf215546Sopenharmony_ci   struct pipe_shader_buffer sb[PIPE_MAX_SHADER_BUFFERS];
74bf215546Sopenharmony_ci   uint32_t enabled_mask;
75bf215546Sopenharmony_ci   uint32_t writable_mask;
76bf215546Sopenharmony_ci};
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_cistruct fd_shaderimg_stateobj {
79bf215546Sopenharmony_ci   struct pipe_image_view si[PIPE_MAX_SHADER_IMAGES];
80bf215546Sopenharmony_ci   uint32_t enabled_mask;
81bf215546Sopenharmony_ci};
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_cistruct fd_vertexbuf_stateobj {
84bf215546Sopenharmony_ci   struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
85bf215546Sopenharmony_ci   unsigned count;
86bf215546Sopenharmony_ci   uint32_t enabled_mask;
87bf215546Sopenharmony_ci};
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_cistruct fd_vertex_stateobj {
90bf215546Sopenharmony_ci   struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
91bf215546Sopenharmony_ci   unsigned num_elements;
92bf215546Sopenharmony_ci};
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_cistruct fd_stream_output_target {
95bf215546Sopenharmony_ci   struct pipe_stream_output_target base;
96bf215546Sopenharmony_ci   struct pipe_resource *offset_buf;
97bf215546Sopenharmony_ci   /* stride of the last stream out recorded to this target, for
98bf215546Sopenharmony_ci    * glDrawTransformFeedback(). */
99bf215546Sopenharmony_ci   uint32_t stride;
100bf215546Sopenharmony_ci};
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_cistruct fd_streamout_stateobj {
103bf215546Sopenharmony_ci   struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
104bf215546Sopenharmony_ci   /* Bitmask of stream that should be reset. */
105bf215546Sopenharmony_ci   unsigned reset;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   unsigned num_targets;
108bf215546Sopenharmony_ci   /* Track offset from vtxcnt for streamout data.  This counter
109bf215546Sopenharmony_ci    * is just incremented by # of vertices on each draw until
110bf215546Sopenharmony_ci    * reset or new streamout buffer bound.
111bf215546Sopenharmony_ci    *
112bf215546Sopenharmony_ci    * When we eventually have GS, the CPU won't actually know the
113bf215546Sopenharmony_ci    * number of vertices per draw, so I think we'll have to do
114bf215546Sopenharmony_ci    * something more clever.
115bf215546Sopenharmony_ci    */
116bf215546Sopenharmony_ci   unsigned offsets[PIPE_MAX_SO_BUFFERS];
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   /* Pre-a6xx, the maximum number of vertices that could be recorded to this
119bf215546Sopenharmony_ci    * set of targets with the current vertex shader.  a6xx and newer, hardware
120bf215546Sopenharmony_ci    * queries are used.
121bf215546Sopenharmony_ci    */
122bf215546Sopenharmony_ci   unsigned max_tf_vtx;
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   /* Pre-a6xx, the number of verts written to the buffers since the last
125bf215546Sopenharmony_ci    * Begin.  Used for overflow checking for SW queries.
126bf215546Sopenharmony_ci    */
127bf215546Sopenharmony_ci   unsigned verts_written;
128bf215546Sopenharmony_ci};
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci#define MAX_GLOBAL_BUFFERS 16
131bf215546Sopenharmony_cistruct fd_global_bindings_stateobj {
132bf215546Sopenharmony_ci   struct pipe_resource *buf[MAX_GLOBAL_BUFFERS];
133bf215546Sopenharmony_ci   uint32_t enabled_mask;
134bf215546Sopenharmony_ci};
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ci/* group together the vertex and vertexbuf state.. for ease of passing
137bf215546Sopenharmony_ci * around, and because various internal operations (gmem<->mem, etc)
138bf215546Sopenharmony_ci * need their own vertex state:
139bf215546Sopenharmony_ci */
140bf215546Sopenharmony_cistruct fd_vertex_state {
141bf215546Sopenharmony_ci   struct fd_vertex_stateobj *vtx;
142bf215546Sopenharmony_ci   struct fd_vertexbuf_stateobj vertexbuf;
143bf215546Sopenharmony_ci};
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci/* global 3d pipeline dirty state: */
146bf215546Sopenharmony_cienum fd_dirty_3d_state {
147bf215546Sopenharmony_ci   FD_DIRTY_BLEND = BIT(0),
148bf215546Sopenharmony_ci   FD_DIRTY_RASTERIZER = BIT(1),
149bf215546Sopenharmony_ci   FD_DIRTY_ZSA = BIT(2),
150bf215546Sopenharmony_ci   FD_DIRTY_BLEND_COLOR = BIT(3),
151bf215546Sopenharmony_ci   FD_DIRTY_STENCIL_REF = BIT(4),
152bf215546Sopenharmony_ci   FD_DIRTY_SAMPLE_MASK = BIT(5),
153bf215546Sopenharmony_ci   FD_DIRTY_FRAMEBUFFER = BIT(6),
154bf215546Sopenharmony_ci   FD_DIRTY_STIPPLE = BIT(7),
155bf215546Sopenharmony_ci   FD_DIRTY_VIEWPORT = BIT(8),
156bf215546Sopenharmony_ci   FD_DIRTY_VTXSTATE = BIT(9),
157bf215546Sopenharmony_ci   FD_DIRTY_VTXBUF = BIT(10),
158bf215546Sopenharmony_ci   FD_DIRTY_MIN_SAMPLES = BIT(11),
159bf215546Sopenharmony_ci   FD_DIRTY_SCISSOR = BIT(12),
160bf215546Sopenharmony_ci   FD_DIRTY_STREAMOUT = BIT(13),
161bf215546Sopenharmony_ci   FD_DIRTY_UCP = BIT(14),
162bf215546Sopenharmony_ci   FD_DIRTY_PROG = BIT(15),
163bf215546Sopenharmony_ci   FD_DIRTY_CONST = BIT(16),
164bf215546Sopenharmony_ci   FD_DIRTY_TEX = BIT(17),
165bf215546Sopenharmony_ci   FD_DIRTY_IMAGE = BIT(18),
166bf215546Sopenharmony_ci   FD_DIRTY_SSBO = BIT(19),
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ci   /* only used by a2xx.. possibly can be removed.. */
169bf215546Sopenharmony_ci   FD_DIRTY_TEXSTATE = BIT(20),
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci   /* fine grained state changes, for cases where state is not orthogonal
172bf215546Sopenharmony_ci    * from hw perspective:
173bf215546Sopenharmony_ci    */
174bf215546Sopenharmony_ci   FD_DIRTY_RASTERIZER_DISCARD = BIT(24),
175bf215546Sopenharmony_ci   FD_DIRTY_RASTERIZER_CLIP_PLANE_ENABLE = BIT(25),
176bf215546Sopenharmony_ci   FD_DIRTY_BLEND_DUAL = BIT(26),
177bf215546Sopenharmony_ci#define NUM_DIRTY_BITS 27
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci   /* additional flag for state requires updated resource tracking: */
180bf215546Sopenharmony_ci   FD_DIRTY_RESOURCE = BIT(31),
181bf215546Sopenharmony_ci};
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci/* per shader-stage dirty state: */
184bf215546Sopenharmony_cienum fd_dirty_shader_state {
185bf215546Sopenharmony_ci   FD_DIRTY_SHADER_PROG = BIT(0),
186bf215546Sopenharmony_ci   FD_DIRTY_SHADER_CONST = BIT(1),
187bf215546Sopenharmony_ci   FD_DIRTY_SHADER_TEX = BIT(2),
188bf215546Sopenharmony_ci   FD_DIRTY_SHADER_SSBO = BIT(3),
189bf215546Sopenharmony_ci   FD_DIRTY_SHADER_IMAGE = BIT(4),
190bf215546Sopenharmony_ci#define NUM_DIRTY_SHADER_BITS 5
191bf215546Sopenharmony_ci};
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci#define MAX_HW_SAMPLE_PROVIDERS 7
194bf215546Sopenharmony_cistruct fd_hw_sample_provider;
195bf215546Sopenharmony_cistruct fd_hw_sample;
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_cistruct ir3_shader_key;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_cistruct fd_context {
200bf215546Sopenharmony_ci   struct pipe_context base;
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   unsigned flags;      /* PIPE_CONTEXT_x */
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   struct threaded_context *tc;
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ci   struct list_head node; /* node in screen->context_list */
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   /* We currently need to serialize emitting GMEM batches, because of
209bf215546Sopenharmony_ci    * VSC state access in the context.
210bf215546Sopenharmony_ci    *
211bf215546Sopenharmony_ci    * In practice this lock should not be contended, since pipe_context
212bf215546Sopenharmony_ci    * use should be single threaded.  But it is needed to protect the
213bf215546Sopenharmony_ci    * case, with batch reordering where a ctxB batch triggers flushing
214bf215546Sopenharmony_ci    * a ctxA batch
215bf215546Sopenharmony_ci    */
216bf215546Sopenharmony_ci   simple_mtx_t gmem_lock;
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci   struct fd_device *dev;
219bf215546Sopenharmony_ci   struct fd_screen *screen;
220bf215546Sopenharmony_ci   struct fd_pipe *pipe;
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   struct blitter_context *blitter dt;
223bf215546Sopenharmony_ci   void *clear_rs_state[2] dt;
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci   /* slab for pipe_transfer allocations: */
226bf215546Sopenharmony_ci   struct slab_child_pool transfer_pool dt;
227bf215546Sopenharmony_ci   struct slab_child_pool transfer_pool_unsync; /* for threaded_context */
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci   struct fd_autotune autotune dt;
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   /**
232bf215546Sopenharmony_ci    * query related state:
233bf215546Sopenharmony_ci    */
234bf215546Sopenharmony_ci   /*@{*/
235bf215546Sopenharmony_ci   /* slabs for fd_hw_sample and fd_hw_sample_period allocations: */
236bf215546Sopenharmony_ci   struct slab_mempool sample_pool dt;
237bf215546Sopenharmony_ci   struct slab_mempool sample_period_pool dt;
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   /* sample-providers for hw queries: */
240bf215546Sopenharmony_ci   const struct fd_hw_sample_provider
241bf215546Sopenharmony_ci      *hw_sample_providers[MAX_HW_SAMPLE_PROVIDERS];
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci   /* list of active queries: */
244bf215546Sopenharmony_ci   struct list_head hw_active_queries dt;
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci   /* sample-providers for accumulating hw queries: */
247bf215546Sopenharmony_ci   const struct fd_acc_sample_provider
248bf215546Sopenharmony_ci      *acc_sample_providers[MAX_HW_SAMPLE_PROVIDERS];
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci   /* list of active accumulating queries: */
251bf215546Sopenharmony_ci   struct list_head acc_active_queries dt;
252bf215546Sopenharmony_ci   /*@}*/
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   uint8_t patch_vertices;
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   /* Whether we need to recheck the active_queries list next
257bf215546Sopenharmony_ci    * fd_batch_update_queries().
258bf215546Sopenharmony_ci    */
259bf215546Sopenharmony_ci   bool update_active_queries dt;
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci   /* Current state of pctx->set_active_query_state() (i.e. "should drawing
262bf215546Sopenharmony_ci    * be counted against non-perfcounter queries")
263bf215546Sopenharmony_ci    */
264bf215546Sopenharmony_ci   bool active_queries dt;
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci   /* shaders used by clear, and gmem->mem blits: */
267bf215546Sopenharmony_ci   struct fd_program_stateobj solid_prog; // TODO move to screen?
268bf215546Sopenharmony_ci   struct fd_program_stateobj solid_layered_prog;
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_ci   /* shaders used by mem->gmem blits: */
271bf215546Sopenharmony_ci   struct fd_program_stateobj
272bf215546Sopenharmony_ci      blit_prog[MAX_RENDER_TARGETS]; // TODO move to screen?
273bf215546Sopenharmony_ci   struct fd_program_stateobj blit_z, blit_zs;
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci   /* Stats/counters:
276bf215546Sopenharmony_ci    */
277bf215546Sopenharmony_ci   struct {
278bf215546Sopenharmony_ci      uint64_t prims_emitted;
279bf215546Sopenharmony_ci      uint64_t prims_generated;
280bf215546Sopenharmony_ci      uint64_t draw_calls;
281bf215546Sopenharmony_ci      uint64_t batch_total, batch_sysmem, batch_gmem, batch_nondraw,
282bf215546Sopenharmony_ci         batch_restore;
283bf215546Sopenharmony_ci      uint64_t staging_uploads, shadow_uploads;
284bf215546Sopenharmony_ci      uint64_t vs_regs, hs_regs, ds_regs, gs_regs, fs_regs;
285bf215546Sopenharmony_ci   } stats dt;
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci   /* Counter for number of users who need sw counters (so we can
288bf215546Sopenharmony_ci    * skip collecting them when not needed)
289bf215546Sopenharmony_ci    */
290bf215546Sopenharmony_ci   unsigned stats_users;
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci   /* Current batch.. the rule here is that you can deref ctx->batch
293bf215546Sopenharmony_ci    * in codepaths from pipe_context entrypoints.  But not in code-
294bf215546Sopenharmony_ci    * paths from fd_batch_flush() (basically, the stuff that gets
295bf215546Sopenharmony_ci    * called from GMEM code), since in those code-paths the batch
296bf215546Sopenharmony_ci    * you care about is not necessarily the same as ctx->batch.
297bf215546Sopenharmony_ci    */
298bf215546Sopenharmony_ci   struct fd_batch *batch dt;
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   /* NULL if there has been rendering since last flush.  Otherwise
301bf215546Sopenharmony_ci    * keeps a reference to the last fence so we can re-use it rather
302bf215546Sopenharmony_ci    * than having to flush no-op batch.
303bf215546Sopenharmony_ci    */
304bf215546Sopenharmony_ci   struct pipe_fence_handle *last_fence dt;
305bf215546Sopenharmony_ci
306bf215546Sopenharmony_ci   /* Fence fd we are told to wait on via ->fence_server_sync() (or -1
307bf215546Sopenharmony_ci    * if none).  The in-fence is transferred over to the batch on the
308bf215546Sopenharmony_ci    * next draw/blit/grid.
309bf215546Sopenharmony_ci    *
310bf215546Sopenharmony_ci    * The reason for this extra complexity is that apps will typically
311bf215546Sopenharmony_ci    * do eglWaitSyncKHR()/etc at the beginning of the frame, before the
312bf215546Sopenharmony_ci    * first draw.  But mesa/st doesn't flush down framebuffer state
313bf215546Sopenharmony_ci    * change until we hit a draw, so at ->fence_server_sync() time, we
314bf215546Sopenharmony_ci    * don't yet have the correct batch.  If we created a batch at that
315bf215546Sopenharmony_ci    * point, it would be the wrong one, and we'd have to flush it pre-
316bf215546Sopenharmony_ci    * maturely, causing us to stall early in the frame where we could
317bf215546Sopenharmony_ci    * be building up cmdstream.
318bf215546Sopenharmony_ci    */
319bf215546Sopenharmony_ci   int in_fence_fd dt;
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci   /* track last known reset status globally and per-context to
322bf215546Sopenharmony_ci    * determine if more resets occurred since then.  If global reset
323bf215546Sopenharmony_ci    * count increases, it means some other context crashed.  If
324bf215546Sopenharmony_ci    * per-context reset count increases, it means we crashed the
325bf215546Sopenharmony_ci    * gpu.
326bf215546Sopenharmony_ci    *
327bf215546Sopenharmony_ci    * Only accessed by front-end thread, never accessed by TC driver
328bf215546Sopenharmony_ci    * thread.
329bf215546Sopenharmony_ci    */
330bf215546Sopenharmony_ci   uint32_t context_reset_count;
331bf215546Sopenharmony_ci   uint32_t global_reset_count;
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci   /* Context sequence #, used for batch-cache key: */
334bf215546Sopenharmony_ci   uint16_t seqno;
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci   /* Cost per draw, used in conjunction with samples-passed history to
337bf215546Sopenharmony_ci    * estimate whether GMEM or bypass is the better option.
338bf215546Sopenharmony_ci    */
339bf215546Sopenharmony_ci   uint8_t draw_cost;
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci   /* Are we in process of shadowing a resource? Used to detect recursion
342bf215546Sopenharmony_ci    * in transfer_map, and skip unneeded synchronization.
343bf215546Sopenharmony_ci    */
344bf215546Sopenharmony_ci   bool in_shadow : 1 dt;
345bf215546Sopenharmony_ci
346bf215546Sopenharmony_ci   /* For catching recursion problems with blit fallback: */
347bf215546Sopenharmony_ci   bool in_blit : 1 dt;
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci   /* points to either scissor or disabled_scissor depending on rast state: */
350bf215546Sopenharmony_ci   struct pipe_scissor_state *current_scissor dt;
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci   struct pipe_scissor_state scissor dt;
353bf215546Sopenharmony_ci
354bf215546Sopenharmony_ci   /* we don't have a disable/enable bit for scissor, so instead we keep
355bf215546Sopenharmony_ci    * a disabled-scissor state which matches the entire bound framebuffer
356bf215546Sopenharmony_ci    * and use that when scissor is not enabled.
357bf215546Sopenharmony_ci    */
358bf215546Sopenharmony_ci   struct pipe_scissor_state disabled_scissor dt;
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   /* Per vsc pipe bo's (a2xx-a5xx): */
361bf215546Sopenharmony_ci   struct fd_bo *vsc_pipe_bo[32] dt;
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   /* Maps generic gallium oriented fd_dirty_3d_state bits to generation
364bf215546Sopenharmony_ci    * specific bitmask of state "groups".
365bf215546Sopenharmony_ci    */
366bf215546Sopenharmony_ci   uint32_t gen_dirty_map[NUM_DIRTY_BITS];
367bf215546Sopenharmony_ci   uint32_t gen_dirty_shader_map[PIPE_SHADER_TYPES][NUM_DIRTY_SHADER_BITS];
368bf215546Sopenharmony_ci
369bf215546Sopenharmony_ci   /* Bitmask of all possible gen_dirty bits: */
370bf215546Sopenharmony_ci   uint32_t gen_all_dirty;
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci   /* Generation specific bitmask of dirty state groups: */
373bf215546Sopenharmony_ci   uint32_t gen_dirty;
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci   /* which state objects need to be re-emit'd: */
376bf215546Sopenharmony_ci   enum fd_dirty_3d_state dirty dt;
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci   /* per shader-stage dirty status: */
379bf215546Sopenharmony_ci   enum fd_dirty_shader_state dirty_shader[PIPE_SHADER_TYPES] dt;
380bf215546Sopenharmony_ci
381bf215546Sopenharmony_ci   void *compute dt;
382bf215546Sopenharmony_ci   struct pipe_blend_state *blend dt;
383bf215546Sopenharmony_ci   struct pipe_rasterizer_state *rasterizer dt;
384bf215546Sopenharmony_ci   struct pipe_depth_stencil_alpha_state *zsa dt;
385bf215546Sopenharmony_ci
386bf215546Sopenharmony_ci   struct fd_texture_stateobj tex[PIPE_SHADER_TYPES] dt;
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci   struct fd_program_stateobj prog dt;
389bf215546Sopenharmony_ci   uint32_t bound_shader_stages dt;
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   struct fd_vertex_state vtx dt;
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ci   struct pipe_blend_color blend_color dt;
394bf215546Sopenharmony_ci   struct pipe_stencil_ref stencil_ref dt;
395bf215546Sopenharmony_ci   unsigned sample_mask dt;
396bf215546Sopenharmony_ci   unsigned min_samples dt;
397bf215546Sopenharmony_ci   /* local context fb state, for when ctx->batch is null: */
398bf215546Sopenharmony_ci   struct pipe_framebuffer_state framebuffer dt;
399bf215546Sopenharmony_ci   struct pipe_poly_stipple stipple dt;
400bf215546Sopenharmony_ci   struct pipe_viewport_state viewport dt;
401bf215546Sopenharmony_ci   struct pipe_scissor_state viewport_scissor dt;
402bf215546Sopenharmony_ci   struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES] dt;
403bf215546Sopenharmony_ci   struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES] dt;
404bf215546Sopenharmony_ci   struct fd_shaderimg_stateobj shaderimg[PIPE_SHADER_TYPES] dt;
405bf215546Sopenharmony_ci   struct fd_streamout_stateobj streamout dt;
406bf215546Sopenharmony_ci   struct fd_global_bindings_stateobj global_bindings dt;
407bf215546Sopenharmony_ci   struct pipe_clip_state ucp dt;
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci   struct pipe_query *cond_query dt;
410bf215546Sopenharmony_ci   bool cond_cond dt; /* inverted rendering condition */
411bf215546Sopenharmony_ci   uint cond_mode dt;
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci   /* Private memory is a memory space where each fiber gets its own piece of
414bf215546Sopenharmony_ci    * memory, in addition to registers. It is backed by a buffer which needs
415bf215546Sopenharmony_ci    * to be large enough to hold the contents of every possible wavefront in
416bf215546Sopenharmony_ci    * every core of the GPU. Because it allocates space via the internal
417bf215546Sopenharmony_ci    * wavefront ID which is shared between all currently executing shaders,
418bf215546Sopenharmony_ci    * the same buffer can be reused by all shaders, as long as all shaders
419bf215546Sopenharmony_ci    * sharing the same buffer use the exact same configuration. There are two
420bf215546Sopenharmony_ci    * inputs to the configuration, the amount of per-fiber space and whether
421bf215546Sopenharmony_ci    * to use the newer per-wave or older per-fiber layout. We only ever
422bf215546Sopenharmony_ci    * increase the size, and shaders with a smaller size requirement simply
423bf215546Sopenharmony_ci    * use the larger existing buffer, so that we only need to keep track of
424bf215546Sopenharmony_ci    * one buffer and its size, but we still need to keep track of per-fiber
425bf215546Sopenharmony_ci    * and per-wave buffers separately so that we never use the same buffer
426bf215546Sopenharmony_ci    * for different layouts. pvtmem[0] is for per-fiber, and pvtmem[1] is for
427bf215546Sopenharmony_ci    * per-wave.
428bf215546Sopenharmony_ci    */
429bf215546Sopenharmony_ci   struct {
430bf215546Sopenharmony_ci      struct fd_bo *bo;
431bf215546Sopenharmony_ci      uint32_t per_fiber_size;
432bf215546Sopenharmony_ci   } pvtmem[2] dt;
433bf215546Sopenharmony_ci
434bf215546Sopenharmony_ci   /* maps per-shader-stage state plus variant key to hw
435bf215546Sopenharmony_ci    * program stateobj:
436bf215546Sopenharmony_ci    */
437bf215546Sopenharmony_ci   struct ir3_cache *shader_cache;
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci   struct util_debug_callback debug;
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci   struct u_trace_context trace_context dt;
442bf215546Sopenharmony_ci
443bf215546Sopenharmony_ci#ifdef HAVE_PERFETTO
444bf215546Sopenharmony_ci   struct fd_perfetto_state perfetto;
445bf215546Sopenharmony_ci#endif
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci   /*
448bf215546Sopenharmony_ci    * Counter to generate submit-ids
449bf215546Sopenharmony_ci    */
450bf215546Sopenharmony_ci   uint32_t submit_count;
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci   /* Called on rebind_resource() for any per-gen cleanup required: */
453bf215546Sopenharmony_ci   void (*rebind_resource)(struct fd_context *ctx, struct fd_resource *rsc) dt;
454bf215546Sopenharmony_ci
455bf215546Sopenharmony_ci   /* GMEM/tile handling fxns: */
456bf215546Sopenharmony_ci   void (*emit_tile_init)(struct fd_batch *batch) dt;
457bf215546Sopenharmony_ci   void (*emit_tile_prep)(struct fd_batch *batch,
458bf215546Sopenharmony_ci                          const struct fd_tile *tile) dt;
459bf215546Sopenharmony_ci   void (*emit_tile_mem2gmem)(struct fd_batch *batch,
460bf215546Sopenharmony_ci                              const struct fd_tile *tile) dt;
461bf215546Sopenharmony_ci   void (*emit_tile_renderprep)(struct fd_batch *batch,
462bf215546Sopenharmony_ci                                const struct fd_tile *tile) dt;
463bf215546Sopenharmony_ci   void (*emit_tile)(struct fd_batch *batch, const struct fd_tile *tile) dt;
464bf215546Sopenharmony_ci   void (*emit_tile_gmem2mem)(struct fd_batch *batch,
465bf215546Sopenharmony_ci                              const struct fd_tile *tile) dt;
466bf215546Sopenharmony_ci   void (*emit_tile_fini)(struct fd_batch *batch) dt; /* optional */
467bf215546Sopenharmony_ci
468bf215546Sopenharmony_ci   /* optional, for GMEM bypass: */
469bf215546Sopenharmony_ci   void (*emit_sysmem_prep)(struct fd_batch *batch) dt;
470bf215546Sopenharmony_ci   void (*emit_sysmem_fini)(struct fd_batch *batch) dt;
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_ci   /* draw: */
473bf215546Sopenharmony_ci   bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info,
474bf215546Sopenharmony_ci			unsigned drawid_offset,
475bf215546Sopenharmony_ci                    const struct pipe_draw_indirect_info *indirect,
476bf215546Sopenharmony_ci			const struct pipe_draw_start_count_bias *draw,
477bf215546Sopenharmony_ci                    unsigned index_offset) dt;
478bf215546Sopenharmony_ci   bool (*clear)(struct fd_context *ctx, unsigned buffers,
479bf215546Sopenharmony_ci                 const union pipe_color_union *color, double depth,
480bf215546Sopenharmony_ci                 unsigned stencil) dt;
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_ci   /* compute: */
483bf215546Sopenharmony_ci   void (*launch_grid)(struct fd_context *ctx,
484bf215546Sopenharmony_ci                       const struct pipe_grid_info *info) dt;
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ci   /* query: */
487bf215546Sopenharmony_ci   struct fd_query *(*create_query)(struct fd_context *ctx, unsigned query_type,
488bf215546Sopenharmony_ci                                    unsigned index);
489bf215546Sopenharmony_ci   void (*query_prepare)(struct fd_batch *batch, uint32_t num_tiles) dt;
490bf215546Sopenharmony_ci   void (*query_prepare_tile)(struct fd_batch *batch, uint32_t n,
491bf215546Sopenharmony_ci                              struct fd_ringbuffer *ring) dt;
492bf215546Sopenharmony_ci   void (*query_update_batch)(struct fd_batch *batch, bool disable_all) dt;
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_ci   /* blitter: */
495bf215546Sopenharmony_ci   bool (*blit)(struct fd_context *ctx, const struct pipe_blit_info *info) dt;
496bf215546Sopenharmony_ci   void (*clear_ubwc)(struct fd_batch *batch, struct fd_resource *rsc) dt;
497bf215546Sopenharmony_ci
498bf215546Sopenharmony_ci   /* uncompress resource, if necessary, to use as the specified format: */
499bf215546Sopenharmony_ci   void (*validate_format)(struct fd_context *ctx, struct fd_resource *rsc,
500bf215546Sopenharmony_ci                           enum pipe_format format) dt;
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_ci   /* handling for barriers: */
503bf215546Sopenharmony_ci   void (*framebuffer_barrier)(struct fd_context *ctx) dt;
504bf215546Sopenharmony_ci
505bf215546Sopenharmony_ci   /* logger: */
506bf215546Sopenharmony_ci   void (*record_timestamp)(struct fd_ringbuffer *ring, struct fd_bo *bo,
507bf215546Sopenharmony_ci                            unsigned offset);
508bf215546Sopenharmony_ci   uint64_t (*ts_to_ns)(uint64_t ts);
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci   /*
511bf215546Sopenharmony_ci    * Common pre-cooked VBO state (used for a3xx and later):
512bf215546Sopenharmony_ci    */
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_ci   /* for clear/gmem->mem vertices, and mem->gmem */
515bf215546Sopenharmony_ci   struct pipe_resource *solid_vbuf;
516bf215546Sopenharmony_ci
517bf215546Sopenharmony_ci   /* for mem->gmem tex coords: */
518bf215546Sopenharmony_ci   struct pipe_resource *blit_texcoord_vbuf;
519bf215546Sopenharmony_ci
520bf215546Sopenharmony_ci   /* vertex state for solid_vbuf:
521bf215546Sopenharmony_ci    *    - solid_vbuf / 12 / R32G32B32_FLOAT
522bf215546Sopenharmony_ci    */
523bf215546Sopenharmony_ci   struct fd_vertex_state solid_vbuf_state;
524bf215546Sopenharmony_ci
525bf215546Sopenharmony_ci   /* vertex state for blit_prog:
526bf215546Sopenharmony_ci    *    - blit_texcoord_vbuf / 8 / R32G32_FLOAT
527bf215546Sopenharmony_ci    *    - solid_vbuf / 12 / R32G32B32_FLOAT
528bf215546Sopenharmony_ci    */
529bf215546Sopenharmony_ci   struct fd_vertex_state blit_vbuf_state;
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci   /*
532bf215546Sopenharmony_ci    * Info about state of previous draw, for state that comes from
533bf215546Sopenharmony_ci    * pipe_draw_info (ie. not part of a CSO).  This allows us to
534bf215546Sopenharmony_ci    * skip some register emit when the state doesn't change from
535bf215546Sopenharmony_ci    * draw-to-draw
536bf215546Sopenharmony_ci    */
537bf215546Sopenharmony_ci   struct {
538bf215546Sopenharmony_ci      bool dirty; /* last draw state unknown */
539bf215546Sopenharmony_ci      bool primitive_restart;
540bf215546Sopenharmony_ci      uint32_t index_start;
541bf215546Sopenharmony_ci      uint32_t instance_start;
542bf215546Sopenharmony_ci      uint32_t restart_index;
543bf215546Sopenharmony_ci      uint32_t streamout_mask;
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_ci      /* some state changes require a different shader variant.  Keep
546bf215546Sopenharmony_ci       * track of this so we know when we need to re-emit shader state
547bf215546Sopenharmony_ci       * due to variant change.  See ir3_fixup_shader_state()
548bf215546Sopenharmony_ci       *
549bf215546Sopenharmony_ci       * (used for a3xx+, NULL otherwise)
550bf215546Sopenharmony_ci       */
551bf215546Sopenharmony_ci      struct ir3_shader_key *key;
552bf215546Sopenharmony_ci
553bf215546Sopenharmony_ci   } last dt;
554bf215546Sopenharmony_ci};
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_cistatic inline struct fd_context *
557bf215546Sopenharmony_cifd_context(struct pipe_context *pctx)
558bf215546Sopenharmony_ci{
559bf215546Sopenharmony_ci   return (struct fd_context *)pctx;
560bf215546Sopenharmony_ci}
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_cistatic inline struct fd_stream_output_target *
563bf215546Sopenharmony_cifd_stream_output_target(struct pipe_stream_output_target *target)
564bf215546Sopenharmony_ci{
565bf215546Sopenharmony_ci   return (struct fd_stream_output_target *)target;
566bf215546Sopenharmony_ci}
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_ci/**
569bf215546Sopenharmony_ci * Does the dirty state require resource tracking, ie. in general
570bf215546Sopenharmony_ci * does it reference some resource.  There are some special cases:
571bf215546Sopenharmony_ci *
572bf215546Sopenharmony_ci * - FD_DIRTY_CONST can reference a resource, but cb0 is handled
573bf215546Sopenharmony_ci *   specially as if it is not a user-buffer, we expect it to be
574bf215546Sopenharmony_ci *   coming from const_uploader, so we can make some assumptions
575bf215546Sopenharmony_ci *   that future transfer_map will be UNSYNCRONIZED
576bf215546Sopenharmony_ci * - FD_DIRTY_ZSA controls how the framebuffer is accessed
577bf215546Sopenharmony_ci * - FD_DIRTY_BLEND needs to update GMEM reason
578bf215546Sopenharmony_ci *
579bf215546Sopenharmony_ci * TODO if we can make assumptions that framebuffer state is bound
580bf215546Sopenharmony_ci * first, before blend/zsa/etc state we can move some of the ZSA/
581bf215546Sopenharmony_ci * BLEND state handling from draw time to bind time.  I think this
582bf215546Sopenharmony_ci * is true of mesa/st, perhaps we can just document it to be a
583bf215546Sopenharmony_ci * frontend requirement?
584bf215546Sopenharmony_ci */
585bf215546Sopenharmony_cistatic inline bool
586bf215546Sopenharmony_cifd_context_dirty_resource(enum fd_dirty_3d_state dirty)
587bf215546Sopenharmony_ci{
588bf215546Sopenharmony_ci   return dirty & (FD_DIRTY_FRAMEBUFFER | FD_DIRTY_ZSA | FD_DIRTY_BLEND |
589bf215546Sopenharmony_ci                   FD_DIRTY_SSBO | FD_DIRTY_IMAGE | FD_DIRTY_VTXBUF |
590bf215546Sopenharmony_ci                   FD_DIRTY_TEX | FD_DIRTY_STREAMOUT);
591bf215546Sopenharmony_ci}
592bf215546Sopenharmony_ci
593bf215546Sopenharmony_ci/* Mark specified non-shader-stage related state as dirty: */
594bf215546Sopenharmony_cistatic inline void
595bf215546Sopenharmony_cifd_context_dirty(struct fd_context *ctx, enum fd_dirty_3d_state dirty) assert_dt
596bf215546Sopenharmony_ci{
597bf215546Sopenharmony_ci   assert(util_is_power_of_two_nonzero(dirty));
598bf215546Sopenharmony_ci   assert(ffs(dirty) <= ARRAY_SIZE(ctx->gen_dirty_map));
599bf215546Sopenharmony_ci
600bf215546Sopenharmony_ci   ctx->gen_dirty |= ctx->gen_dirty_map[ffs(dirty) - 1];
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci   if (fd_context_dirty_resource(dirty))
603bf215546Sopenharmony_ci      or_mask(dirty, FD_DIRTY_RESOURCE);
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_ci   or_mask(ctx->dirty, dirty);
606bf215546Sopenharmony_ci}
607bf215546Sopenharmony_ci
608bf215546Sopenharmony_cistatic inline void
609bf215546Sopenharmony_cifd_context_dirty_shader(struct fd_context *ctx, enum pipe_shader_type shader,
610bf215546Sopenharmony_ci                        enum fd_dirty_shader_state dirty) assert_dt
611bf215546Sopenharmony_ci{
612bf215546Sopenharmony_ci   const enum fd_dirty_3d_state map[] = {
613bf215546Sopenharmony_ci      FD_DIRTY_PROG, FD_DIRTY_CONST, FD_DIRTY_TEX,
614bf215546Sopenharmony_ci      FD_DIRTY_SSBO, FD_DIRTY_IMAGE,
615bf215546Sopenharmony_ci   };
616bf215546Sopenharmony_ci
617bf215546Sopenharmony_ci   /* Need to update the table above if these shift: */
618bf215546Sopenharmony_ci   STATIC_ASSERT(FD_DIRTY_SHADER_PROG == BIT(0));
619bf215546Sopenharmony_ci   STATIC_ASSERT(FD_DIRTY_SHADER_CONST == BIT(1));
620bf215546Sopenharmony_ci   STATIC_ASSERT(FD_DIRTY_SHADER_TEX == BIT(2));
621bf215546Sopenharmony_ci   STATIC_ASSERT(FD_DIRTY_SHADER_SSBO == BIT(3));
622bf215546Sopenharmony_ci   STATIC_ASSERT(FD_DIRTY_SHADER_IMAGE == BIT(4));
623bf215546Sopenharmony_ci
624bf215546Sopenharmony_ci   assert(util_is_power_of_two_nonzero(dirty));
625bf215546Sopenharmony_ci   assert(ffs(dirty) <= ARRAY_SIZE(map));
626bf215546Sopenharmony_ci
627bf215546Sopenharmony_ci   ctx->gen_dirty |= ctx->gen_dirty_shader_map[shader][ffs(dirty) - 1];
628bf215546Sopenharmony_ci
629bf215546Sopenharmony_ci   or_mask(ctx->dirty_shader[shader], dirty);
630bf215546Sopenharmony_ci   fd_context_dirty(ctx, map[ffs(dirty) - 1]);
631bf215546Sopenharmony_ci}
632bf215546Sopenharmony_ci
633bf215546Sopenharmony_ci/* mark all state dirty: */
634bf215546Sopenharmony_cistatic inline void
635bf215546Sopenharmony_cifd_context_all_dirty(struct fd_context *ctx) assert_dt
636bf215546Sopenharmony_ci{
637bf215546Sopenharmony_ci   ctx->last.dirty = true;
638bf215546Sopenharmony_ci   ctx->dirty = (enum fd_dirty_3d_state) ~0;
639bf215546Sopenharmony_ci
640bf215546Sopenharmony_ci   /* NOTE: don't use ~0 for gen_dirty, because the gen specific
641bf215546Sopenharmony_ci    * emit code will loop over all the bits:
642bf215546Sopenharmony_ci    */
643bf215546Sopenharmony_ci   ctx->gen_dirty = ctx->gen_all_dirty;
644bf215546Sopenharmony_ci
645bf215546Sopenharmony_ci   for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++)
646bf215546Sopenharmony_ci      ctx->dirty_shader[i] = (enum fd_dirty_shader_state) ~0;
647bf215546Sopenharmony_ci}
648bf215546Sopenharmony_ci
649bf215546Sopenharmony_cistatic inline void
650bf215546Sopenharmony_cifd_context_all_clean(struct fd_context *ctx) assert_dt
651bf215546Sopenharmony_ci{
652bf215546Sopenharmony_ci   ctx->last.dirty = false;
653bf215546Sopenharmony_ci   ctx->dirty = (enum fd_dirty_3d_state)0;
654bf215546Sopenharmony_ci   ctx->gen_dirty = 0;
655bf215546Sopenharmony_ci   for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++) {
656bf215546Sopenharmony_ci      /* don't mark compute state as clean, since it is not emitted
657bf215546Sopenharmony_ci       * during normal draw call.  The places that call _all_dirty(),
658bf215546Sopenharmony_ci       * it is safe to mark compute state dirty as well, but the
659bf215546Sopenharmony_ci       * inverse is not true.
660bf215546Sopenharmony_ci       */
661bf215546Sopenharmony_ci      if (i == PIPE_SHADER_COMPUTE)
662bf215546Sopenharmony_ci         continue;
663bf215546Sopenharmony_ci      ctx->dirty_shader[i] = (enum fd_dirty_shader_state)0;
664bf215546Sopenharmony_ci   }
665bf215546Sopenharmony_ci}
666bf215546Sopenharmony_ci
667bf215546Sopenharmony_ci/**
668bf215546Sopenharmony_ci * Add mapping between global dirty bit and generation specific dirty
669bf215546Sopenharmony_ci * bit.
670bf215546Sopenharmony_ci */
671bf215546Sopenharmony_cistatic inline void
672bf215546Sopenharmony_cifd_context_add_map(struct fd_context *ctx, enum fd_dirty_3d_state dirty,
673bf215546Sopenharmony_ci                   uint32_t gen_dirty)
674bf215546Sopenharmony_ci{
675bf215546Sopenharmony_ci   u_foreach_bit (b, dirty) {
676bf215546Sopenharmony_ci      ctx->gen_dirty_map[b] |= gen_dirty;
677bf215546Sopenharmony_ci   }
678bf215546Sopenharmony_ci   ctx->gen_all_dirty |= gen_dirty;
679bf215546Sopenharmony_ci}
680bf215546Sopenharmony_ci
681bf215546Sopenharmony_ci/**
682bf215546Sopenharmony_ci * Add mapping between shader stage specific dirty bit and generation
683bf215546Sopenharmony_ci * specific dirty bit
684bf215546Sopenharmony_ci */
685bf215546Sopenharmony_cistatic inline void
686bf215546Sopenharmony_cifd_context_add_shader_map(struct fd_context *ctx, enum pipe_shader_type shader,
687bf215546Sopenharmony_ci                          enum fd_dirty_shader_state dirty, uint32_t gen_dirty)
688bf215546Sopenharmony_ci{
689bf215546Sopenharmony_ci   u_foreach_bit (b, dirty) {
690bf215546Sopenharmony_ci      ctx->gen_dirty_shader_map[shader][b] |= gen_dirty;
691bf215546Sopenharmony_ci   }
692bf215546Sopenharmony_ci   ctx->gen_all_dirty |= gen_dirty;
693bf215546Sopenharmony_ci}
694bf215546Sopenharmony_ci
695bf215546Sopenharmony_cistatic inline struct pipe_scissor_state *
696bf215546Sopenharmony_cifd_context_get_scissor(struct fd_context *ctx) assert_dt
697bf215546Sopenharmony_ci{
698bf215546Sopenharmony_ci   return ctx->current_scissor;
699bf215546Sopenharmony_ci}
700bf215546Sopenharmony_ci
701bf215546Sopenharmony_civoid fd_context_switch_from(struct fd_context *ctx) assert_dt;
702bf215546Sopenharmony_civoid fd_context_switch_to(struct fd_context *ctx,
703bf215546Sopenharmony_ci                          struct fd_batch *batch) assert_dt;
704bf215546Sopenharmony_cistruct fd_batch *fd_context_batch(struct fd_context *ctx) assert_dt;
705bf215546Sopenharmony_cistruct fd_batch *fd_context_batch_locked(struct fd_context *ctx) assert_dt;
706bf215546Sopenharmony_ci
707bf215546Sopenharmony_civoid fd_context_setup_common_vbos(struct fd_context *ctx);
708bf215546Sopenharmony_civoid fd_context_cleanup_common_vbos(struct fd_context *ctx);
709bf215546Sopenharmony_civoid fd_emit_string(struct fd_ringbuffer *ring, const char *string, int len);
710bf215546Sopenharmony_civoid fd_emit_string5(struct fd_ringbuffer *ring, const char *string, int len);
711bf215546Sopenharmony_ci
712bf215546Sopenharmony_cistruct pipe_context *fd_context_init(struct fd_context *ctx,
713bf215546Sopenharmony_ci                                     struct pipe_screen *pscreen,
714bf215546Sopenharmony_ci                                     void *priv, unsigned flags);
715bf215546Sopenharmony_cistruct pipe_context *fd_context_init_tc(struct pipe_context *pctx,
716bf215546Sopenharmony_ci                                        unsigned flags);
717bf215546Sopenharmony_ci
718bf215546Sopenharmony_civoid fd_context_destroy(struct pipe_context *pctx) assert_dt;
719bf215546Sopenharmony_ci
720bf215546Sopenharmony_ci#ifdef __cplusplus
721bf215546Sopenharmony_ci}
722bf215546Sopenharmony_ci#endif
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci#endif /* FREEDRENO_CONTEXT_H_ */
725