Path: blob/21.2-virgl/src/gallium/drivers/iris/iris_batch.h
4565 views
/*1* Copyright © 2017 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#ifndef IRIS_BATCH_DOT_H24#define IRIS_BATCH_DOT_H2526#include <stdint.h>27#include <stdbool.h>28#include <string.h>2930#include "util/u_dynarray.h"3132#include "drm-uapi/i915_drm.h"33#include "common/intel_decoder.h"3435#include "iris_fence.h"36#include "iris_fine_fence.h"3738struct iris_context;3940/* The kernel assumes batchbuffers are smaller than 256kB. */41#define MAX_BATCH_SIZE (256 * 1024)4243/* Terminating the batch takes either 4 bytes for MI_BATCH_BUFFER_END or 1244* bytes for MI_BATCH_BUFFER_START (when chaining). Plus another 24 bytes for45* the seqno write (using PIPE_CONTROL), and another 24 bytes for the ISP46* invalidation pipe control.47*/48#define BATCH_RESERVED 604950/* Our target batch size - flush approximately at this point. */51#define BATCH_SZ (64 * 1024 - BATCH_RESERVED)5253enum iris_batch_name {54IRIS_BATCH_RENDER,55IRIS_BATCH_COMPUTE,56};5758#define IRIS_BATCH_COUNT 25960struct iris_batch {61struct iris_context *ice;62struct iris_screen *screen;63struct pipe_debug_callback *dbg;64struct pipe_device_reset_callback *reset;6566/** What batch is this? (e.g. IRIS_BATCH_RENDER/COMPUTE) */67enum iris_batch_name name;6869/** Current batchbuffer being queued up. */70struct iris_bo *bo;71void *map;72void *map_next;7374/** Size of the primary batch being submitted to execbuf (in bytes). */75unsigned primary_batch_size;7677/** Total size of all chained batches (in bytes). */78unsigned total_chained_batch_size;7980/** Last Surface State Base Address set in this hardware context. */81uint64_t last_surface_base_address;8283uint32_t hw_ctx_id;8485/** The validation list */86struct drm_i915_gem_exec_object2 *validation_list;87struct iris_bo **exec_bos;88int exec_count;89int exec_array_size;9091/** Whether INTEL_BLACKHOLE_RENDER is enabled in the batch (aka first92* instruction is a MI_BATCH_BUFFER_END).93*/94bool noop_enabled;9596/**97* A list of iris_syncobjs associated with this batch.98*99* The first list entry will always be a signalling sync-point, indicating100* that this batch has completed. The others are likely to be sync-points101* to wait on before executing the batch.102*/103struct util_dynarray syncobjs;104105/** A list of drm_i915_exec_fences to have execbuf signal or wait on */106struct util_dynarray exec_fences;107108/** The amount of aperture space (in bytes) used by all exec_bos */109int aperture_space;110111struct {112/** Uploader to use for sequence numbers */113struct u_upload_mgr *uploader;114115/** GPU buffer and CPU map where our seqno's will be written. */116struct iris_state_ref ref;117uint32_t *map;118119/** The sequence number to write the next time we add a fence. */120uint32_t next;121} fine_fences;122123/** A seqno (and syncobj) for the last batch that was submitted. */124struct iris_fine_fence *last_fence;125126/** List of other batches which we might need to flush to use a BO */127struct iris_batch *other_batches[IRIS_BATCH_COUNT - 1];128129struct {130/**131* Set of struct brw_bo * that have been rendered to within this132* batchbuffer and would need flushing before being used from another133* cache domain that isn't coherent with it (i.e. the sampler).134*/135struct hash_table *render;136} cache;137138struct intel_batch_decode_ctx decoder;139struct hash_table_u64 *state_sizes;140141/**142* Matrix representation of the cache coherency status of the GPU at the143* current end point of the batch. For every i and j,144* coherent_seqnos[i][j] denotes the seqno of the most recent flush of145* cache domain j visible to cache domain i (which obviously implies that146* coherent_seqnos[i][i] is the most recent flush of cache domain i). This147* can be used to efficiently determine whether synchronization is148* necessary before accessing data from cache domain i if it was previously149* accessed from another cache domain j.150*/151uint64_t coherent_seqnos[NUM_IRIS_DOMAINS][NUM_IRIS_DOMAINS];152153/**154* Sequence number used to track the completion of any subsequent memory155* operations in the batch until the next sync boundary.156*/157uint64_t next_seqno;158159/** Have we emitted any draw calls to this batch? */160bool contains_draw;161162/** Have we emitted any draw calls with next_seqno? */163bool contains_draw_with_next_seqno;164165/** Batch contains fence signal operation. */166bool contains_fence_signal;167168/**169* Number of times iris_batch_sync_region_start() has been called without a170* matching iris_batch_sync_region_end() on this batch.171*/172uint32_t sync_region_depth;173174uint32_t last_aux_map_state;175struct iris_measure_batch *measure;176};177178void iris_init_batch(struct iris_context *ice,179enum iris_batch_name name,180int priority);181void iris_chain_to_new_batch(struct iris_batch *batch);182void iris_batch_free(struct iris_batch *batch);183void iris_batch_maybe_flush(struct iris_batch *batch, unsigned estimate);184185void _iris_batch_flush(struct iris_batch *batch, const char *file, int line);186#define iris_batch_flush(batch) _iris_batch_flush((batch), __FILE__, __LINE__)187188bool iris_batch_references(struct iris_batch *batch, struct iris_bo *bo);189190bool iris_batch_prepare_noop(struct iris_batch *batch, bool noop_enable);191192#define RELOC_WRITE EXEC_OBJECT_WRITE193194void iris_use_pinned_bo(struct iris_batch *batch, struct iris_bo *bo,195bool writable, enum iris_domain access);196197enum pipe_reset_status iris_batch_check_for_reset(struct iris_batch *batch);198199static inline unsigned200iris_batch_bytes_used(struct iris_batch *batch)201{202return batch->map_next - batch->map;203}204205/**206* Ensure the current command buffer has \param size bytes of space207* remaining. If not, this creates a secondary batch buffer and emits208* a jump from the primary batch to the start of the secondary.209*210* Most callers want iris_get_command_space() instead.211*/212static inline void213iris_require_command_space(struct iris_batch *batch, unsigned size)214{215const unsigned required_bytes = iris_batch_bytes_used(batch) + size;216217if (required_bytes >= BATCH_SZ) {218iris_chain_to_new_batch(batch);219}220}221222/**223* Allocate space in the current command buffer, and return a pointer224* to the mapped area so the caller can write commands there.225*226* This should be called whenever emitting commands.227*/228static inline void *229iris_get_command_space(struct iris_batch *batch, unsigned bytes)230{231iris_require_command_space(batch, bytes);232void *map = batch->map_next;233batch->map_next += bytes;234return map;235}236237/**238* Helper to emit GPU commands - allocates space, copies them there.239*/240static inline void241iris_batch_emit(struct iris_batch *batch, const void *data, unsigned size)242{243void *map = iris_get_command_space(batch, size);244memcpy(map, data, size);245}246247/**248* Get a pointer to the batch's signalling syncobj. Does not refcount.249*/250static inline struct iris_syncobj *251iris_batch_get_signal_syncobj(struct iris_batch *batch)252{253/* The signalling syncobj is the first one in the list. */254struct iris_syncobj *syncobj =255((struct iris_syncobj **) util_dynarray_begin(&batch->syncobjs))[0];256return syncobj;257}258259260/**261* Take a reference to the batch's signalling syncobj.262*263* Callers can use this to wait for the the current batch under construction264* to complete (after flushing it).265*/266static inline void267iris_batch_reference_signal_syncobj(struct iris_batch *batch,268struct iris_syncobj **out_syncobj)269{270struct iris_syncobj *syncobj = iris_batch_get_signal_syncobj(batch);271iris_syncobj_reference(batch->screen, out_syncobj, syncobj);272}273274/**275* Record the size of a piece of state for use in INTEL_DEBUG=bat printing.276*/277static inline void278iris_record_state_size(struct hash_table_u64 *ht,279uint32_t offset_from_base,280uint32_t size)281{282if (ht) {283_mesa_hash_table_u64_insert(ht, offset_from_base,284(void *)(uintptr_t) size);285}286}287288/**289* Mark the start of a region in the batch with stable synchronization290* sequence number. Any buffer object accessed by the batch buffer only needs291* to be marked once (e.g. via iris_bo_bump_seqno()) within a region delimited292* by iris_batch_sync_region_start() and iris_batch_sync_region_end().293*/294static inline void295iris_batch_sync_region_start(struct iris_batch *batch)296{297batch->sync_region_depth++;298}299300/**301* Mark the end of a region in the batch with stable synchronization sequence302* number. Should be called once after each call to303* iris_batch_sync_region_start().304*/305static inline void306iris_batch_sync_region_end(struct iris_batch *batch)307{308assert(batch->sync_region_depth);309batch->sync_region_depth--;310}311312/**313* Start a new synchronization section at the current point of the batch,314* unless disallowed by a previous iris_batch_sync_region_start().315*/316static inline void317iris_batch_sync_boundary(struct iris_batch *batch)318{319if (!batch->sync_region_depth) {320batch->contains_draw_with_next_seqno = false;321batch->next_seqno = p_atomic_inc_return(&batch->screen->last_seqno);322assert(batch->next_seqno > 0);323}324}325326/**327* Update the cache coherency status of the batch to reflect a flush of the328* specified caching domain.329*/330static inline void331iris_batch_mark_flush_sync(struct iris_batch *batch,332enum iris_domain access)333{334batch->coherent_seqnos[access][access] = batch->next_seqno - 1;335}336337/**338* Update the cache coherency status of the batch to reflect an invalidation339* of the specified caching domain. All prior flushes of other caches will be340* considered visible to the specified caching domain.341*/342static inline void343iris_batch_mark_invalidate_sync(struct iris_batch *batch,344enum iris_domain access)345{346for (unsigned i = 0; i < NUM_IRIS_DOMAINS; i++)347batch->coherent_seqnos[access][i] = batch->coherent_seqnos[i][i];348}349350/**351* Update the cache coherency status of the batch to reflect a reset. All352* previously accessed data can be considered visible to every caching domain353* thanks to the kernel's heavyweight flushing at batch buffer boundaries.354*/355static inline void356iris_batch_mark_reset_sync(struct iris_batch *batch)357{358for (unsigned i = 0; i < NUM_IRIS_DOMAINS; i++)359for (unsigned j = 0; j < NUM_IRIS_DOMAINS; j++)360batch->coherent_seqnos[i][j] = batch->next_seqno - 1;361}362363#endif364365366