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