1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2017 Intel Corporation
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
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#ifndef IRIS_BATCH_DOT_H
25bf215546Sopenharmony_ci#define IRIS_BATCH_DOT_H
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include <stdint.h>
28bf215546Sopenharmony_ci#include <stdbool.h>
29bf215546Sopenharmony_ci#include <string.h>
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "util/u_dynarray.h"
32bf215546Sopenharmony_ci#include "util/perf/u_trace.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "drm-uapi/i915_drm.h"
35bf215546Sopenharmony_ci#include "common/intel_decoder.h"
36bf215546Sopenharmony_ci#include "ds/intel_driver_ds.h"
37bf215546Sopenharmony_ci#include "ds/intel_tracepoints.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci#include "iris_fence.h"
40bf215546Sopenharmony_ci#include "iris_fine_fence.h"
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_cistruct iris_context;
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci/* The kernel assumes batchbuffers are smaller than 256kB. */
45bf215546Sopenharmony_ci#define MAX_BATCH_SIZE (256 * 1024)
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci/* Terminating the batch takes either 4 bytes for MI_BATCH_BUFFER_END or 12
48bf215546Sopenharmony_ci * bytes for MI_BATCH_BUFFER_START (when chaining).  Plus another 24 bytes for
49bf215546Sopenharmony_ci * the seqno write (using PIPE_CONTROL), and another 24 bytes for the ISP
50bf215546Sopenharmony_ci * invalidation pipe control.
51bf215546Sopenharmony_ci */
52bf215546Sopenharmony_ci#define BATCH_RESERVED 60
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci/* Our target batch size - flush approximately at this point. */
55bf215546Sopenharmony_ci#define BATCH_SZ (64 * 1024 - BATCH_RESERVED)
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_cienum iris_batch_name {
58bf215546Sopenharmony_ci   IRIS_BATCH_RENDER,
59bf215546Sopenharmony_ci   IRIS_BATCH_COMPUTE,
60bf215546Sopenharmony_ci   IRIS_BATCH_BLITTER,
61bf215546Sopenharmony_ci};
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_cistruct iris_batch {
64bf215546Sopenharmony_ci   struct iris_context *ice;
65bf215546Sopenharmony_ci   struct iris_screen *screen;
66bf215546Sopenharmony_ci   struct util_debug_callback *dbg;
67bf215546Sopenharmony_ci   struct pipe_device_reset_callback *reset;
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci   /** What batch is this? (e.g. IRIS_BATCH_RENDER/COMPUTE) */
70bf215546Sopenharmony_ci   enum iris_batch_name name;
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci   /** Current batchbuffer being queued up. */
73bf215546Sopenharmony_ci   struct iris_bo *bo;
74bf215546Sopenharmony_ci   void *map;
75bf215546Sopenharmony_ci   void *map_next;
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci   /** Size of the primary batch being submitted to execbuf (in bytes). */
78bf215546Sopenharmony_ci   unsigned primary_batch_size;
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   /** Total size of all chained batches (in bytes). */
81bf215546Sopenharmony_ci   unsigned total_chained_batch_size;
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   /** Last binder address set in this hardware context. */
84bf215546Sopenharmony_ci   uint64_t last_binder_address;
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   uint32_t ctx_id;
87bf215546Sopenharmony_ci   uint32_t exec_flags;
88bf215546Sopenharmony_ci   bool has_engines_context;
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci   /** A list of all BOs referenced by this batch */
91bf215546Sopenharmony_ci   struct iris_bo **exec_bos;
92bf215546Sopenharmony_ci   int exec_count;
93bf215546Sopenharmony_ci   int exec_array_size;
94bf215546Sopenharmony_ci   /** Bitset of whether this batch writes to BO `i'. */
95bf215546Sopenharmony_ci   BITSET_WORD *bos_written;
96bf215546Sopenharmony_ci   uint32_t max_gem_handle;
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci   /** Whether INTEL_BLACKHOLE_RENDER is enabled in the batch (aka first
99bf215546Sopenharmony_ci    * instruction is a MI_BATCH_BUFFER_END).
100bf215546Sopenharmony_ci    */
101bf215546Sopenharmony_ci   bool noop_enabled;
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci   /** Whether the first utrace point has been recorded.
104bf215546Sopenharmony_ci    */
105bf215546Sopenharmony_ci   bool begin_trace_recorded;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   /**
108bf215546Sopenharmony_ci    * A list of iris_syncobjs associated with this batch.
109bf215546Sopenharmony_ci    *
110bf215546Sopenharmony_ci    * The first list entry will always be a signalling sync-point, indicating
111bf215546Sopenharmony_ci    * that this batch has completed.  The others are likely to be sync-points
112bf215546Sopenharmony_ci    * to wait on before executing the batch.
113bf215546Sopenharmony_ci    */
114bf215546Sopenharmony_ci   struct util_dynarray syncobjs;
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   /** A list of drm_i915_exec_fences to have execbuf signal or wait on */
117bf215546Sopenharmony_ci   struct util_dynarray exec_fences;
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci   /** The amount of aperture space (in bytes) used by all exec_bos */
120bf215546Sopenharmony_ci   int aperture_space;
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci   struct {
123bf215546Sopenharmony_ci      /** Uploader to use for sequence numbers */
124bf215546Sopenharmony_ci      struct u_upload_mgr *uploader;
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci      /** GPU buffer and CPU map where our seqno's will be written. */
127bf215546Sopenharmony_ci      struct iris_state_ref ref;
128bf215546Sopenharmony_ci      uint32_t *map;
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci      /** The sequence number to write the next time we add a fence. */
131bf215546Sopenharmony_ci      uint32_t next;
132bf215546Sopenharmony_ci   } fine_fences;
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   /** A seqno (and syncobj) for the last batch that was submitted. */
135bf215546Sopenharmony_ci   struct iris_fine_fence *last_fence;
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   /** List of other batches which we might need to flush to use a BO */
138bf215546Sopenharmony_ci   struct iris_batch *other_batches[IRIS_BATCH_COUNT - 1];
139bf215546Sopenharmony_ci   unsigned num_other_batches;
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci   struct {
142bf215546Sopenharmony_ci      /**
143bf215546Sopenharmony_ci       * Set of struct brw_bo * that have been rendered to within this
144bf215546Sopenharmony_ci       * batchbuffer and would need flushing before being used from another
145bf215546Sopenharmony_ci       * cache domain that isn't coherent with it (i.e. the sampler).
146bf215546Sopenharmony_ci       */
147bf215546Sopenharmony_ci      struct hash_table *render;
148bf215546Sopenharmony_ci   } cache;
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   struct intel_batch_decode_ctx decoder;
151bf215546Sopenharmony_ci   struct hash_table_u64 *state_sizes;
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   /**
154bf215546Sopenharmony_ci    * Matrix representation of the cache coherency status of the GPU at the
155bf215546Sopenharmony_ci    * current end point of the batch.  For every i and j,
156bf215546Sopenharmony_ci    * coherent_seqnos[i][j] denotes the seqno of the most recent flush of
157bf215546Sopenharmony_ci    * cache domain j visible to cache domain i (which obviously implies that
158bf215546Sopenharmony_ci    * coherent_seqnos[i][i] is the most recent flush of cache domain i).  This
159bf215546Sopenharmony_ci    * can be used to efficiently determine whether synchronization is
160bf215546Sopenharmony_ci    * necessary before accessing data from cache domain i if it was previously
161bf215546Sopenharmony_ci    * accessed from another cache domain j.
162bf215546Sopenharmony_ci    */
163bf215546Sopenharmony_ci   uint64_t coherent_seqnos[NUM_IRIS_DOMAINS][NUM_IRIS_DOMAINS];
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   /**
166bf215546Sopenharmony_ci    * A vector representing the cache coherency status of the L3.  For each
167bf215546Sopenharmony_ci    * cache domain i, l3_coherent_seqnos[i] denotes the seqno of the most
168bf215546Sopenharmony_ci    * recent flush of that domain which is visible to L3 clients.
169bf215546Sopenharmony_ci    */
170bf215546Sopenharmony_ci   uint64_t l3_coherent_seqnos[NUM_IRIS_DOMAINS];
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   /**
173bf215546Sopenharmony_ci    * Sequence number used to track the completion of any subsequent memory
174bf215546Sopenharmony_ci    * operations in the batch until the next sync boundary.
175bf215546Sopenharmony_ci    */
176bf215546Sopenharmony_ci   uint64_t next_seqno;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   /** Have we emitted any draw calls to this batch? */
179bf215546Sopenharmony_ci   bool contains_draw;
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   /** Have we emitted any draw calls with next_seqno? */
182bf215546Sopenharmony_ci   bool contains_draw_with_next_seqno;
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci   /** Batch contains fence signal operation. */
185bf215546Sopenharmony_ci   bool contains_fence_signal;
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci   /**
188bf215546Sopenharmony_ci    * Number of times iris_batch_sync_region_start() has been called without a
189bf215546Sopenharmony_ci    * matching iris_batch_sync_region_end() on this batch.
190bf215546Sopenharmony_ci    */
191bf215546Sopenharmony_ci   uint32_t sync_region_depth;
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci   uint32_t last_aux_map_state;
194bf215546Sopenharmony_ci   struct iris_measure_batch *measure;
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   /** Where tracepoints are recorded */
197bf215546Sopenharmony_ci   struct u_trace trace;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   /** Batch wrapper structure for perfetto */
200bf215546Sopenharmony_ci   struct intel_ds_queue *ds;
201bf215546Sopenharmony_ci};
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_civoid iris_init_batches(struct iris_context *ice, int priority);
204bf215546Sopenharmony_civoid iris_chain_to_new_batch(struct iris_batch *batch);
205bf215546Sopenharmony_civoid iris_destroy_batches(struct iris_context *ice);
206bf215546Sopenharmony_civoid iris_batch_maybe_flush(struct iris_batch *batch, unsigned estimate);
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_civoid _iris_batch_flush(struct iris_batch *batch, const char *file, int line);
209bf215546Sopenharmony_ci#define iris_batch_flush(batch) _iris_batch_flush((batch), __FILE__, __LINE__)
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_cibool iris_batch_references(struct iris_batch *batch, struct iris_bo *bo);
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_cibool iris_batch_prepare_noop(struct iris_batch *batch, bool noop_enable);
214bf215546Sopenharmony_ci
215bf215546Sopenharmony_ci#define RELOC_WRITE EXEC_OBJECT_WRITE
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_civoid iris_use_pinned_bo(struct iris_batch *batch, struct iris_bo *bo,
218bf215546Sopenharmony_ci                        bool writable, enum iris_domain access);
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_cienum pipe_reset_status iris_batch_check_for_reset(struct iris_batch *batch);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_cistatic inline unsigned
223bf215546Sopenharmony_ciiris_batch_bytes_used(struct iris_batch *batch)
224bf215546Sopenharmony_ci{
225bf215546Sopenharmony_ci   return batch->map_next - batch->map;
226bf215546Sopenharmony_ci}
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci/**
229bf215546Sopenharmony_ci * Ensure the current command buffer has \param size bytes of space
230bf215546Sopenharmony_ci * remaining.  If not, this creates a secondary batch buffer and emits
231bf215546Sopenharmony_ci * a jump from the primary batch to the start of the secondary.
232bf215546Sopenharmony_ci *
233bf215546Sopenharmony_ci * Most callers want iris_get_command_space() instead.
234bf215546Sopenharmony_ci */
235bf215546Sopenharmony_cistatic inline void
236bf215546Sopenharmony_ciiris_require_command_space(struct iris_batch *batch, unsigned size)
237bf215546Sopenharmony_ci{
238bf215546Sopenharmony_ci   const unsigned required_bytes = iris_batch_bytes_used(batch) + size;
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci   if (required_bytes >= BATCH_SZ) {
241bf215546Sopenharmony_ci      iris_chain_to_new_batch(batch);
242bf215546Sopenharmony_ci   }
243bf215546Sopenharmony_ci}
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci/**
246bf215546Sopenharmony_ci * Allocate space in the current command buffer, and return a pointer
247bf215546Sopenharmony_ci * to the mapped area so the caller can write commands there.
248bf215546Sopenharmony_ci *
249bf215546Sopenharmony_ci * This should be called whenever emitting commands.
250bf215546Sopenharmony_ci */
251bf215546Sopenharmony_cistatic inline void *
252bf215546Sopenharmony_ciiris_get_command_space(struct iris_batch *batch, unsigned bytes)
253bf215546Sopenharmony_ci{
254bf215546Sopenharmony_ci   if (!batch->begin_trace_recorded) {
255bf215546Sopenharmony_ci      batch->begin_trace_recorded = true;
256bf215546Sopenharmony_ci      trace_intel_begin_batch(&batch->trace);
257bf215546Sopenharmony_ci   }
258bf215546Sopenharmony_ci   iris_require_command_space(batch, bytes);
259bf215546Sopenharmony_ci   void *map = batch->map_next;
260bf215546Sopenharmony_ci   batch->map_next += bytes;
261bf215546Sopenharmony_ci   return map;
262bf215546Sopenharmony_ci}
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci/**
265bf215546Sopenharmony_ci * Helper to emit GPU commands - allocates space, copies them there.
266bf215546Sopenharmony_ci */
267bf215546Sopenharmony_cistatic inline void
268bf215546Sopenharmony_ciiris_batch_emit(struct iris_batch *batch, const void *data, unsigned size)
269bf215546Sopenharmony_ci{
270bf215546Sopenharmony_ci   void *map = iris_get_command_space(batch, size);
271bf215546Sopenharmony_ci   memcpy(map, data, size);
272bf215546Sopenharmony_ci}
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci/**
275bf215546Sopenharmony_ci * Get a pointer to the batch's signalling syncobj.  Does not refcount.
276bf215546Sopenharmony_ci */
277bf215546Sopenharmony_cistatic inline struct iris_syncobj *
278bf215546Sopenharmony_ciiris_batch_get_signal_syncobj(struct iris_batch *batch)
279bf215546Sopenharmony_ci{
280bf215546Sopenharmony_ci   /* The signalling syncobj is the first one in the list. */
281bf215546Sopenharmony_ci   struct iris_syncobj *syncobj =
282bf215546Sopenharmony_ci      ((struct iris_syncobj **) util_dynarray_begin(&batch->syncobjs))[0];
283bf215546Sopenharmony_ci   return syncobj;
284bf215546Sopenharmony_ci}
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci/**
288bf215546Sopenharmony_ci * Take a reference to the batch's signalling syncobj.
289bf215546Sopenharmony_ci *
290bf215546Sopenharmony_ci * Callers can use this to wait for the the current batch under construction
291bf215546Sopenharmony_ci * to complete (after flushing it).
292bf215546Sopenharmony_ci */
293bf215546Sopenharmony_cistatic inline void
294bf215546Sopenharmony_ciiris_batch_reference_signal_syncobj(struct iris_batch *batch,
295bf215546Sopenharmony_ci                                   struct iris_syncobj **out_syncobj)
296bf215546Sopenharmony_ci{
297bf215546Sopenharmony_ci   struct iris_syncobj *syncobj = iris_batch_get_signal_syncobj(batch);
298bf215546Sopenharmony_ci   iris_syncobj_reference(batch->screen->bufmgr, out_syncobj, syncobj);
299bf215546Sopenharmony_ci}
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci/**
302bf215546Sopenharmony_ci * Record the size of a piece of state for use in INTEL_DEBUG=bat printing.
303bf215546Sopenharmony_ci */
304bf215546Sopenharmony_cistatic inline void
305bf215546Sopenharmony_ciiris_record_state_size(struct hash_table_u64 *ht,
306bf215546Sopenharmony_ci                       uint32_t offset_from_base,
307bf215546Sopenharmony_ci                       uint32_t size)
308bf215546Sopenharmony_ci{
309bf215546Sopenharmony_ci   if (ht) {
310bf215546Sopenharmony_ci      _mesa_hash_table_u64_insert(ht, offset_from_base,
311bf215546Sopenharmony_ci                                  (void *)(uintptr_t) size);
312bf215546Sopenharmony_ci   }
313bf215546Sopenharmony_ci}
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci/**
316bf215546Sopenharmony_ci * Mark the start of a region in the batch with stable synchronization
317bf215546Sopenharmony_ci * sequence number.  Any buffer object accessed by the batch buffer only needs
318bf215546Sopenharmony_ci * to be marked once (e.g. via iris_bo_bump_seqno()) within a region delimited
319bf215546Sopenharmony_ci * by iris_batch_sync_region_start() and iris_batch_sync_region_end().
320bf215546Sopenharmony_ci */
321bf215546Sopenharmony_cistatic inline void
322bf215546Sopenharmony_ciiris_batch_sync_region_start(struct iris_batch *batch)
323bf215546Sopenharmony_ci{
324bf215546Sopenharmony_ci   batch->sync_region_depth++;
325bf215546Sopenharmony_ci}
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci/**
328bf215546Sopenharmony_ci * Mark the end of a region in the batch with stable synchronization sequence
329bf215546Sopenharmony_ci * number.  Should be called once after each call to
330bf215546Sopenharmony_ci * iris_batch_sync_region_start().
331bf215546Sopenharmony_ci */
332bf215546Sopenharmony_cistatic inline void
333bf215546Sopenharmony_ciiris_batch_sync_region_end(struct iris_batch *batch)
334bf215546Sopenharmony_ci{
335bf215546Sopenharmony_ci   assert(batch->sync_region_depth);
336bf215546Sopenharmony_ci   batch->sync_region_depth--;
337bf215546Sopenharmony_ci}
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci/**
340bf215546Sopenharmony_ci * Start a new synchronization section at the current point of the batch,
341bf215546Sopenharmony_ci * unless disallowed by a previous iris_batch_sync_region_start().
342bf215546Sopenharmony_ci */
343bf215546Sopenharmony_cistatic inline void
344bf215546Sopenharmony_ciiris_batch_sync_boundary(struct iris_batch *batch)
345bf215546Sopenharmony_ci{
346bf215546Sopenharmony_ci   if (!batch->sync_region_depth) {
347bf215546Sopenharmony_ci      batch->contains_draw_with_next_seqno = false;
348bf215546Sopenharmony_ci      batch->next_seqno = p_atomic_inc_return(&batch->screen->last_seqno);
349bf215546Sopenharmony_ci      assert(batch->next_seqno > 0);
350bf215546Sopenharmony_ci   }
351bf215546Sopenharmony_ci}
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci/**
354bf215546Sopenharmony_ci * Update the cache coherency status of the batch to reflect a flush of the
355bf215546Sopenharmony_ci * specified caching domain.
356bf215546Sopenharmony_ci */
357bf215546Sopenharmony_cistatic inline void
358bf215546Sopenharmony_ciiris_batch_mark_flush_sync(struct iris_batch *batch,
359bf215546Sopenharmony_ci                           enum iris_domain access)
360bf215546Sopenharmony_ci{
361bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &batch->screen->devinfo;
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   if (iris_domain_is_l3_coherent(devinfo, access))
364bf215546Sopenharmony_ci      batch->l3_coherent_seqnos[access] = batch->next_seqno - 1;
365bf215546Sopenharmony_ci   else
366bf215546Sopenharmony_ci      batch->coherent_seqnos[access][access] = batch->next_seqno - 1;
367bf215546Sopenharmony_ci}
368bf215546Sopenharmony_ci
369bf215546Sopenharmony_ci/**
370bf215546Sopenharmony_ci * Update the cache coherency status of the batch to reflect an invalidation
371bf215546Sopenharmony_ci * of the specified caching domain.  All prior flushes of other caches will be
372bf215546Sopenharmony_ci * considered visible to the specified caching domain.
373bf215546Sopenharmony_ci */
374bf215546Sopenharmony_cistatic inline void
375bf215546Sopenharmony_ciiris_batch_mark_invalidate_sync(struct iris_batch *batch,
376bf215546Sopenharmony_ci                                enum iris_domain access)
377bf215546Sopenharmony_ci{
378bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &batch->screen->devinfo;
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci   for (unsigned i = 0; i < NUM_IRIS_DOMAINS; i++) {
381bf215546Sopenharmony_ci      if (i == access)
382bf215546Sopenharmony_ci         continue;
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci      if (iris_domain_is_l3_coherent(devinfo, access)) {
385bf215546Sopenharmony_ci         if (iris_domain_is_read_only(access)) {
386bf215546Sopenharmony_ci            /* Invalidating a L3-coherent read-only domain "access" also
387bf215546Sopenharmony_ci             * triggers an invalidation of any matching L3 cachelines as well.
388bf215546Sopenharmony_ci             *
389bf215546Sopenharmony_ci             * If domain 'i' is L3-coherent, it sees the latest data in L3,
390bf215546Sopenharmony_ci             * otherwise it sees the latest globally-observable data.
391bf215546Sopenharmony_ci             */
392bf215546Sopenharmony_ci            batch->coherent_seqnos[access][i] =
393bf215546Sopenharmony_ci               iris_domain_is_l3_coherent(devinfo, i) ?
394bf215546Sopenharmony_ci               batch->l3_coherent_seqnos[i] : batch->coherent_seqnos[i][i];
395bf215546Sopenharmony_ci         } else {
396bf215546Sopenharmony_ci            /* Invalidating L3-coherent write domains does not trigger
397bf215546Sopenharmony_ci             * an invalidation of any matching L3 cachelines, however.
398bf215546Sopenharmony_ci             *
399bf215546Sopenharmony_ci             * It sees the latest data from domain i visible to L3 clients.
400bf215546Sopenharmony_ci             */
401bf215546Sopenharmony_ci            batch->coherent_seqnos[access][i] = batch->l3_coherent_seqnos[i];
402bf215546Sopenharmony_ci         }
403bf215546Sopenharmony_ci      } else {
404bf215546Sopenharmony_ci         /* "access" isn't L3-coherent, so invalidating it means it sees the
405bf215546Sopenharmony_ci          * most recent globally-observable data from domain i.
406bf215546Sopenharmony_ci          */
407bf215546Sopenharmony_ci         batch->coherent_seqnos[access][i] = batch->coherent_seqnos[i][i];
408bf215546Sopenharmony_ci      }
409bf215546Sopenharmony_ci   }
410bf215546Sopenharmony_ci}
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci/**
413bf215546Sopenharmony_ci * Update the cache coherency status of the batch to reflect a reset.  All
414bf215546Sopenharmony_ci * previously accessed data can be considered visible to every caching domain
415bf215546Sopenharmony_ci * thanks to the kernel's heavyweight flushing at batch buffer boundaries.
416bf215546Sopenharmony_ci */
417bf215546Sopenharmony_cistatic inline void
418bf215546Sopenharmony_ciiris_batch_mark_reset_sync(struct iris_batch *batch)
419bf215546Sopenharmony_ci{
420bf215546Sopenharmony_ci   for (unsigned i = 0; i < NUM_IRIS_DOMAINS; i++) {
421bf215546Sopenharmony_ci      batch->l3_coherent_seqnos[i] = batch->next_seqno - 1;
422bf215546Sopenharmony_ci      for (unsigned j = 0; j < NUM_IRIS_DOMAINS; j++)
423bf215546Sopenharmony_ci         batch->coherent_seqnos[i][j] = batch->next_seqno - 1;
424bf215546Sopenharmony_ci   }
425bf215546Sopenharmony_ci}
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_ciconst char *
428bf215546Sopenharmony_ciiris_batch_name_to_string(enum iris_batch_name name);
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci#define iris_foreach_batch(ice, batch)                \
431bf215546Sopenharmony_ci   for (struct iris_batch *batch = &ice->batches[0];  \
432bf215546Sopenharmony_ci        batch <= &ice->batches[((struct iris_screen *)ice->ctx.screen)->devinfo.ver >= 12 ? IRIS_BATCH_BLITTER : IRIS_BATCH_COMPUTE]; \
433bf215546Sopenharmony_ci        ++batch)
434bf215546Sopenharmony_ci
435bf215546Sopenharmony_ci#endif
436