103b705cfSriastradh/* 203b705cfSriastradh * Copyright (c) 2011 Intel Corporation 303b705cfSriastradh * 403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a 503b705cfSriastradh * copy of this software and associated documentation files (the "Software"), 603b705cfSriastradh * to deal in the Software without restriction, including without limitation 703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the 903b705cfSriastradh * Software is furnished to do so, subject to the following conditions: 1003b705cfSriastradh * 1103b705cfSriastradh * The above copyright notice and this permission notice (including the next 1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the 1303b705cfSriastradh * Software. 1403b705cfSriastradh * 1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2103b705cfSriastradh * SOFTWARE. 2203b705cfSriastradh * 2303b705cfSriastradh * Authors: 2403b705cfSriastradh * Chris Wilson <chris@chris-wilson.co.uk> 2503b705cfSriastradh * 2603b705cfSriastradh */ 2703b705cfSriastradh 2803b705cfSriastradh#ifndef KGEM_H 2903b705cfSriastradh#define KGEM_H 3003b705cfSriastradh 3103b705cfSriastradh#include <stdint.h> 3203b705cfSriastradh#include <stdbool.h> 3303b705cfSriastradh#include <stdarg.h> 3403b705cfSriastradh 3503b705cfSriastradh#include <i915_drm.h> 3603b705cfSriastradh 3703b705cfSriastradh#include "compiler.h" 3813496ba1Ssnj#include "debug.h" 3903b705cfSriastradh 4003b705cfSriastradhstruct kgem_bo { 4103b705cfSriastradh struct kgem_request *rq; 4203b705cfSriastradh#define RQ(rq) ((struct kgem_request *)((uintptr_t)(rq) & ~3)) 4303b705cfSriastradh#define RQ_RING(rq) ((uintptr_t)(rq) & 3) 4403b705cfSriastradh#define RQ_IS_BLT(rq) (RQ_RING(rq) == KGEM_BLT) 45fe8aea9eSmrg#define RQ_IS_RENDER(rq) (RQ_RING(rq) == KGEM_RENDER) 4642542f5fSchristos#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring))) 4742542f5fSchristos 4803b705cfSriastradh struct drm_i915_gem_exec_object2 *exec; 4903b705cfSriastradh 5003b705cfSriastradh struct kgem_bo *proxy; 5103b705cfSriastradh 5203b705cfSriastradh struct list list; 5303b705cfSriastradh struct list request; 5403b705cfSriastradh struct list vma; 5503b705cfSriastradh 5642542f5fSchristos void *map__cpu; 5742542f5fSchristos void *map__gtt; 5813496ba1Ssnj void *map__wc; 5903b705cfSriastradh#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3)) 6003b705cfSriastradh 6103b705cfSriastradh struct kgem_bo_binding { 6203b705cfSriastradh struct kgem_bo_binding *next; 6303b705cfSriastradh uint32_t format; 6403b705cfSriastradh uint16_t offset; 6503b705cfSriastradh } binding; 6603b705cfSriastradh 6742542f5fSchristos uint64_t presumed_offset; 6803b705cfSriastradh uint32_t unique_id; 6903b705cfSriastradh uint32_t refcnt; 7003b705cfSriastradh uint32_t handle; 7103b705cfSriastradh uint32_t target_handle; 7203b705cfSriastradh uint32_t delta; 7342542f5fSchristos uint32_t active_scanout; 7403b705cfSriastradh union { 7503b705cfSriastradh struct { 7603b705cfSriastradh uint32_t count:27; 7703b705cfSriastradh#define PAGE_SIZE 4096 7803b705cfSriastradh uint32_t bucket:5; 7903b705cfSriastradh#define NUM_CACHE_BUCKETS 16 8003b705cfSriastradh#define MAX_CACHE_SIZE (1 << (NUM_CACHE_BUCKETS+12)) 8103b705cfSriastradh } pages; 8203b705cfSriastradh uint32_t bytes; 8303b705cfSriastradh } size; 8403b705cfSriastradh uint32_t pitch : 18; /* max 128k */ 8503b705cfSriastradh uint32_t tiling : 2; 8603b705cfSriastradh uint32_t reusable : 1; 8703b705cfSriastradh uint32_t gpu_dirty : 1; 8803b705cfSriastradh uint32_t gtt_dirty : 1; 8903b705cfSriastradh uint32_t domain : 2; 9003b705cfSriastradh uint32_t needs_flush : 1; 9103b705cfSriastradh uint32_t snoop : 1; 9203b705cfSriastradh uint32_t io : 1; 9303b705cfSriastradh uint32_t flush : 1; 9403b705cfSriastradh uint32_t scanout : 1; 9542542f5fSchristos uint32_t prime : 1; 9603b705cfSriastradh uint32_t purged : 1; 9703b705cfSriastradh}; 9803b705cfSriastradh#define DOMAIN_NONE 0 9903b705cfSriastradh#define DOMAIN_CPU 1 10003b705cfSriastradh#define DOMAIN_GTT 2 10103b705cfSriastradh#define DOMAIN_GPU 3 10203b705cfSriastradh 10303b705cfSriastradhstruct kgem_request { 10403b705cfSriastradh struct list list; 10503b705cfSriastradh struct kgem_bo *bo; 10603b705cfSriastradh struct list buffers; 107fe8aea9eSmrg unsigned ring; 10803b705cfSriastradh}; 10903b705cfSriastradh 11003b705cfSriastradhenum { 11103b705cfSriastradh MAP_GTT = 0, 11203b705cfSriastradh MAP_CPU, 11303b705cfSriastradh NUM_MAP_TYPES, 11403b705cfSriastradh}; 11503b705cfSriastradh 116fe8aea9eSmrgtypedef void (*memcpy_box_func)(const void *src, void *dst, int bpp, 117fe8aea9eSmrg int32_t src_stride, int32_t dst_stride, 118fe8aea9eSmrg int16_t src_x, int16_t src_y, 119fe8aea9eSmrg int16_t dst_x, int16_t dst_y, 120fe8aea9eSmrg uint16_t width, uint16_t height); 121fe8aea9eSmrg 12203b705cfSriastradhstruct kgem { 12342542f5fSchristos unsigned wedged; 12413496ba1Ssnj int fd; 12503b705cfSriastradh unsigned gen; 12603b705cfSriastradh 12703b705cfSriastradh uint32_t unique_id; 12803b705cfSriastradh 12913496ba1Ssnj uint16_t nbatch; 13013496ba1Ssnj uint16_t surface; 13113496ba1Ssnj uint16_t nexec; 13213496ba1Ssnj uint16_t nreloc; 13313496ba1Ssnj uint16_t nreloc__self; 13413496ba1Ssnj uint16_t nfence; 13513496ba1Ssnj uint16_t batch_size; 13613496ba1Ssnj 13713496ba1Ssnj uint32_t *batch; 13813496ba1Ssnj 13903b705cfSriastradh enum kgem_mode { 14003b705cfSriastradh /* order matches I915_EXEC_RING ordering */ 14103b705cfSriastradh KGEM_NONE = 0, 14203b705cfSriastradh KGEM_RENDER, 14303b705cfSriastradh KGEM_BSD, 14403b705cfSriastradh KGEM_BLT, 14503b705cfSriastradh } mode, ring; 14603b705cfSriastradh 14703b705cfSriastradh struct list flushing; 14803b705cfSriastradh struct list large; 14903b705cfSriastradh struct list large_inactive; 15003b705cfSriastradh struct list active[NUM_CACHE_BUCKETS][3]; 15103b705cfSriastradh struct list inactive[NUM_CACHE_BUCKETS]; 15203b705cfSriastradh struct list pinned_batches[2]; 15303b705cfSriastradh struct list snoop; 15403b705cfSriastradh struct list scanout; 15503b705cfSriastradh struct list batch_buffers, active_buffers; 15603b705cfSriastradh 15703b705cfSriastradh struct list requests[2]; 15813496ba1Ssnj struct kgem_request *fence[2]; 15903b705cfSriastradh struct kgem_request *next_request; 16003b705cfSriastradh struct kgem_request static_request; 16103b705cfSriastradh 16203b705cfSriastradh struct { 16303b705cfSriastradh struct list inactive[NUM_CACHE_BUCKETS]; 16403b705cfSriastradh int16_t count; 16503b705cfSriastradh } vma[NUM_MAP_TYPES]; 16603b705cfSriastradh 167fe8aea9eSmrg uint32_t bcs_state; 168fe8aea9eSmrg 16903b705cfSriastradh uint32_t batch_flags; 17003b705cfSriastradh uint32_t batch_flags_base; 17103b705cfSriastradh#define I915_EXEC_SECURE (1<<9) 17203b705cfSriastradh#define LOCAL_EXEC_OBJECT_WRITE (1<<2) 17303b705cfSriastradh 17403b705cfSriastradh uint32_t flush:1; 17503b705cfSriastradh uint32_t need_expire:1; 17603b705cfSriastradh uint32_t need_purge:1; 17703b705cfSriastradh uint32_t need_retire:1; 17803b705cfSriastradh uint32_t need_throttle:1; 17942542f5fSchristos uint32_t needs_semaphore:1; 18042542f5fSchristos uint32_t needs_reservation:1; 18103b705cfSriastradh uint32_t scanout_busy:1; 18203b705cfSriastradh uint32_t busy:1; 18303b705cfSriastradh 18403b705cfSriastradh uint32_t has_create2 :1; 18503b705cfSriastradh uint32_t has_userptr :1; 18603b705cfSriastradh uint32_t has_blt :1; 18703b705cfSriastradh uint32_t has_relaxed_fencing :1; 18803b705cfSriastradh uint32_t has_relaxed_delta :1; 18903b705cfSriastradh uint32_t has_semaphores :1; 19003b705cfSriastradh uint32_t has_secure_batches :1; 19103b705cfSriastradh uint32_t has_pinned_batches :1; 19203b705cfSriastradh uint32_t has_caching :1; 193fe8aea9eSmrg uint32_t has_coherent_mmap_gtt :1; 19403b705cfSriastradh uint32_t has_llc :1; 19503b705cfSriastradh uint32_t has_wt :1; 19603b705cfSriastradh uint32_t has_no_reloc :1; 19703b705cfSriastradh uint32_t has_handle_lut :1; 19813496ba1Ssnj uint32_t has_wc_mmap :1; 199fe8aea9eSmrg uint32_t has_dirtyfb :1; 20003b705cfSriastradh 201fe8aea9eSmrg uint32_t can_fence :1; 20203b705cfSriastradh uint32_t can_blt_cpu :1; 203fe8aea9eSmrg uint32_t can_blt_y :1; 20442542f5fSchristos uint32_t can_render_y :1; 205fe8aea9eSmrg uint32_t can_scanout_y :1; 206fe8aea9eSmrg 207fe8aea9eSmrg uint32_t needs_dirtyfb :1; 20803b705cfSriastradh 20903b705cfSriastradh uint16_t fence_max; 21003b705cfSriastradh uint16_t half_cpu_cache_pages; 21142542f5fSchristos uint32_t aperture_total, aperture_high, aperture_low, aperture_mappable, aperture_fenceable; 21242542f5fSchristos uint32_t aperture, aperture_fenced, aperture_max_fence; 21303b705cfSriastradh uint32_t max_upload_tile_size, max_copy_tile_size; 21403b705cfSriastradh uint32_t max_gpu_size, max_cpu_size; 21503b705cfSriastradh uint32_t large_object_size, max_object_size; 21603b705cfSriastradh uint32_t buffer_size; 21703b705cfSriastradh 21803b705cfSriastradh void (*context_switch)(struct kgem *kgem, int new_mode); 21903b705cfSriastradh void (*retire)(struct kgem *kgem); 22003b705cfSriastradh void (*expire)(struct kgem *kgem); 22103b705cfSriastradh 222fe8aea9eSmrg memcpy_box_func memcpy_to_tiled_x; 223fe8aea9eSmrg memcpy_box_func memcpy_from_tiled_x; 224fe8aea9eSmrg memcpy_box_func memcpy_between_tiled_x; 22503b705cfSriastradh 22613496ba1Ssnj struct kgem_bo *batch_bo; 22713496ba1Ssnj 22803b705cfSriastradh uint16_t reloc__self[256]; 22903b705cfSriastradh struct drm_i915_gem_exec_object2 exec[384] page_aligned; 23003b705cfSriastradh struct drm_i915_gem_relocation_entry reloc[8192] page_aligned; 23103b705cfSriastradh 23203b705cfSriastradh#ifdef DEBUG_MEMORY 23303b705cfSriastradh struct { 23403b705cfSriastradh int bo_allocs; 23503b705cfSriastradh size_t bo_bytes; 23603b705cfSriastradh } debug_memory; 23703b705cfSriastradh#endif 23803b705cfSriastradh}; 23903b705cfSriastradh 24003b705cfSriastradh#define KGEM_MAX_DEFERRED_VBO 16 24103b705cfSriastradh 242fe8aea9eSmrg#define KGEM_BATCH_RESERVED 8 /* LRI(SWCTRL) + END */ 24303b705cfSriastradh#define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO) 24403b705cfSriastradh#define KGEM_EXEC_RESERVED (1+KGEM_MAX_DEFERRED_VBO) 24503b705cfSriastradh 24603b705cfSriastradh#ifndef ARRAY_SIZE 24703b705cfSriastradh#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 24803b705cfSriastradh#endif 24903b705cfSriastradh 25003b705cfSriastradh#define KGEM_BATCH_SIZE(K) ((K)->batch_size-KGEM_BATCH_RESERVED) 25103b705cfSriastradh#define KGEM_EXEC_SIZE(K) (int)(ARRAY_SIZE((K)->exec)-KGEM_EXEC_RESERVED) 25203b705cfSriastradh#define KGEM_RELOC_SIZE(K) (int)(ARRAY_SIZE((K)->reloc)-KGEM_RELOC_RESERVED) 25303b705cfSriastradh 25403b705cfSriastradhvoid kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen); 25503b705cfSriastradhvoid kgem_reset(struct kgem *kgem); 25603b705cfSriastradh 25703b705cfSriastradhstruct kgem_bo *kgem_create_map(struct kgem *kgem, 25803b705cfSriastradh void *ptr, uint32_t size, 25903b705cfSriastradh bool read_only); 26003b705cfSriastradh 26103b705cfSriastradhstruct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name); 26203b705cfSriastradhstruct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size); 26303b705cfSriastradhint kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo); 26403b705cfSriastradh 26503b705cfSriastradhstruct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags); 26603b705cfSriastradhstruct kgem_bo *kgem_create_proxy(struct kgem *kgem, 26703b705cfSriastradh struct kgem_bo *target, 26803b705cfSriastradh int offset, int length); 26903b705cfSriastradh 27003b705cfSriastradhstruct kgem_bo *kgem_upload_source_image(struct kgem *kgem, 27103b705cfSriastradh const void *data, 27203b705cfSriastradh const BoxRec *box, 27303b705cfSriastradh int stride, int bpp); 27403b705cfSriastradhvoid kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr); 27503b705cfSriastradh 27603b705cfSriastradhint kgem_choose_tiling(struct kgem *kgem, 27703b705cfSriastradh int tiling, int width, int height, int bpp); 27803b705cfSriastradhunsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth); 27903b705cfSriastradh#define KGEM_CAN_CREATE_GPU 0x1 28003b705cfSriastradh#define KGEM_CAN_CREATE_CPU 0x2 28103b705cfSriastradh#define KGEM_CAN_CREATE_LARGE 0x4 28203b705cfSriastradh#define KGEM_CAN_CREATE_GTT 0x8 28342542f5fSchristos#define KGEM_CAN_CREATE_TILED 0x10 28403b705cfSriastradh 28542542f5fSchristosbool kgem_check_surface_size(struct kgem *kgem, 28642542f5fSchristos uint32_t width, 28742542f5fSchristos uint32_t height, 28842542f5fSchristos uint32_t bpp, 28942542f5fSchristos uint32_t tiling, 29042542f5fSchristos uint32_t pitch, 29142542f5fSchristos uint32_t size); 29203b705cfSriastradh 29303b705cfSriastradhstruct kgem_bo * 29403b705cfSriastradhkgem_replace_bo(struct kgem *kgem, 29503b705cfSriastradh struct kgem_bo *src, 29603b705cfSriastradh uint32_t width, 29703b705cfSriastradh uint32_t height, 29803b705cfSriastradh uint32_t pitch, 29903b705cfSriastradh uint32_t bpp); 30003b705cfSriastradhenum { 30103b705cfSriastradh CREATE_EXACT = 0x1, 30203b705cfSriastradh CREATE_INACTIVE = 0x2, 30303b705cfSriastradh CREATE_CPU_MAP = 0x4, 30403b705cfSriastradh CREATE_GTT_MAP = 0x8, 30503b705cfSriastradh CREATE_SCANOUT = 0x10, 30603b705cfSriastradh CREATE_PRIME = 0x20, 30703b705cfSriastradh CREATE_TEMPORARY = 0x40, 30803b705cfSriastradh CREATE_CACHED = 0x80, 30913496ba1Ssnj CREATE_UNCACHED = 0x100, 31013496ba1Ssnj CREATE_NO_RETIRE = 0x200, 31113496ba1Ssnj CREATE_NO_THROTTLE = 0x400, 31203b705cfSriastradh}; 31303b705cfSriastradhstruct kgem_bo *kgem_create_2d(struct kgem *kgem, 31403b705cfSriastradh int width, 31503b705cfSriastradh int height, 31603b705cfSriastradh int bpp, 31703b705cfSriastradh int tiling, 31803b705cfSriastradh uint32_t flags); 31903b705cfSriastradhstruct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem, 32003b705cfSriastradh int width, 32103b705cfSriastradh int height, 32203b705cfSriastradh int bpp, 32303b705cfSriastradh uint32_t flags); 32403b705cfSriastradh 32542542f5fSchristosbool kgem_bo_convert_to_gpu(struct kgem *kgem, 32642542f5fSchristos struct kgem_bo *bo, 32742542f5fSchristos unsigned flags); 32842542f5fSchristos 329fe8aea9eSmrgbool kgem_bo_is_fenced(struct kgem *kgem, struct kgem_bo *bo); 33003b705cfSriastradhuint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format); 33103b705cfSriastradhvoid kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset); 33203b705cfSriastradh 33303b705cfSriastradhbool kgem_retire(struct kgem *kgem); 33442542f5fSchristosvoid kgem_retire__buffers(struct kgem *kgem); 33542542f5fSchristos 33642542f5fSchristosstatic inline bool kgem_bo_discard_cache(struct kgem_bo *bo, bool force) 33742542f5fSchristos{ 33842542f5fSchristos if (bo == NULL || bo->proxy == NULL) 33942542f5fSchristos return false; 34042542f5fSchristos 34142542f5fSchristos if (force) 34242542f5fSchristos return true; 34342542f5fSchristos 34442542f5fSchristos if (bo->proxy->rq) 34542542f5fSchristos return false; 34642542f5fSchristos 34742542f5fSchristos return bo->snoop; 34842542f5fSchristos} 34903b705cfSriastradh 35003b705cfSriastradhbool __kgem_ring_is_idle(struct kgem *kgem, int ring); 35103b705cfSriastradhstatic inline bool kgem_ring_is_idle(struct kgem *kgem, int ring) 35203b705cfSriastradh{ 35303b705cfSriastradh ring = ring == KGEM_BLT; 35403b705cfSriastradh 355fe8aea9eSmrg if (kgem->needs_semaphore && 356fe8aea9eSmrg !list_is_empty(&kgem->requests[!ring]) && 357fe8aea9eSmrg !__kgem_ring_is_idle(kgem, !ring)) 358fe8aea9eSmrg return false; 359fe8aea9eSmrg 36003b705cfSriastradh if (list_is_empty(&kgem->requests[ring])) 36103b705cfSriastradh return true; 36203b705cfSriastradh 36303b705cfSriastradh return __kgem_ring_is_idle(kgem, ring); 36403b705cfSriastradh} 36503b705cfSriastradh 36603b705cfSriastradhstatic inline bool kgem_is_idle(struct kgem *kgem) 36703b705cfSriastradh{ 36803b705cfSriastradh if (!kgem->need_retire) 36903b705cfSriastradh return true; 37003b705cfSriastradh 37103b705cfSriastradh return kgem_ring_is_idle(kgem, kgem->ring); 37203b705cfSriastradh} 37303b705cfSriastradh 37403b705cfSriastradhstatic inline bool __kgem_ring_empty(struct kgem *kgem) 37503b705cfSriastradh{ 37603b705cfSriastradh return list_is_empty(&kgem->requests[kgem->ring == KGEM_BLT]); 37703b705cfSriastradh} 37803b705cfSriastradh 37903b705cfSriastradhvoid _kgem_submit(struct kgem *kgem); 38003b705cfSriastradhstatic inline void kgem_submit(struct kgem *kgem) 38103b705cfSriastradh{ 38203b705cfSriastradh if (kgem->nbatch) 38303b705cfSriastradh _kgem_submit(kgem); 38403b705cfSriastradh} 38503b705cfSriastradh 38603b705cfSriastradhstatic inline void kgem_bo_submit(struct kgem *kgem, struct kgem_bo *bo) 38703b705cfSriastradh{ 38842542f5fSchristos if (bo->exec == NULL) 38942542f5fSchristos return; 39042542f5fSchristos 39142542f5fSchristos assert(bo->refcnt); 39242542f5fSchristos _kgem_submit(kgem); 39303b705cfSriastradh} 39403b705cfSriastradh 39503b705cfSriastradhvoid kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo); 39603b705cfSriastradh 39703b705cfSriastradhstatic inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo) 39803b705cfSriastradh{ 39903b705cfSriastradh assert(bo->refcnt); 40003b705cfSriastradh bo->refcnt++; 40103b705cfSriastradh return bo; 40203b705cfSriastradh} 40303b705cfSriastradh 40403b705cfSriastradhvoid _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo); 40503b705cfSriastradhstatic inline void kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) 40603b705cfSriastradh{ 40703b705cfSriastradh assert(bo->refcnt); 408fe8aea9eSmrg assert(bo->refcnt > bo->active_scanout); 40903b705cfSriastradh if (--bo->refcnt == 0) 41003b705cfSriastradh _kgem_bo_destroy(kgem, bo); 41103b705cfSriastradh} 41203b705cfSriastradh 41303b705cfSriastradhvoid kgem_clear_dirty(struct kgem *kgem); 41403b705cfSriastradh 41503b705cfSriastradhstatic inline void kgem_set_mode(struct kgem *kgem, 41603b705cfSriastradh enum kgem_mode mode, 41703b705cfSriastradh struct kgem_bo *bo) 41803b705cfSriastradh{ 419fe8aea9eSmrg warn_unless(!kgem->wedged); 42003b705cfSriastradh 42103b705cfSriastradh#if DEBUG_FLUSH_BATCH 42203b705cfSriastradh kgem_submit(kgem); 42303b705cfSriastradh#endif 42403b705cfSriastradh 425fe8aea9eSmrg if (kgem->nreloc && bo->rq == NULL && kgem_ring_is_idle(kgem, kgem->ring)) { 42642542f5fSchristos DBG(("%s: flushing before new bo\n", __FUNCTION__)); 42703b705cfSriastradh _kgem_submit(kgem); 42842542f5fSchristos } 42903b705cfSriastradh 43003b705cfSriastradh if (kgem->mode == mode) 43103b705cfSriastradh return; 43203b705cfSriastradh 43303b705cfSriastradh kgem->context_switch(kgem, mode); 43403b705cfSriastradh kgem->mode = mode; 43503b705cfSriastradh} 43603b705cfSriastradh 43703b705cfSriastradhstatic inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode) 43803b705cfSriastradh{ 43903b705cfSriastradh assert(kgem->mode == KGEM_NONE); 44003b705cfSriastradh assert(kgem->nbatch == 0); 441fe8aea9eSmrg warn_unless(!kgem->wedged); 44203b705cfSriastradh kgem->context_switch(kgem, mode); 44303b705cfSriastradh kgem->mode = mode; 44403b705cfSriastradh} 44503b705cfSriastradh 44613496ba1Ssnjstatic inline int kgem_batch_space(struct kgem *kgem) 44713496ba1Ssnj{ 44813496ba1Ssnj int rem = kgem->surface - kgem->nbatch; 44913496ba1Ssnj assert(rem > 0); 45013496ba1Ssnj return rem - KGEM_BATCH_RESERVED; 45113496ba1Ssnj} 45213496ba1Ssnj 45303b705cfSriastradhstatic inline bool kgem_check_batch(struct kgem *kgem, int num_dwords) 45403b705cfSriastradh{ 45503b705cfSriastradh assert(num_dwords > 0); 45603b705cfSriastradh assert(kgem->nbatch < kgem->surface); 45703b705cfSriastradh assert(kgem->surface <= kgem->batch_size); 45803b705cfSriastradh return likely(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED <= kgem->surface); 45903b705cfSriastradh} 46003b705cfSriastradh 46103b705cfSriastradhstatic inline bool kgem_check_reloc(struct kgem *kgem, int n) 46203b705cfSriastradh{ 46303b705cfSriastradh assert(kgem->nreloc <= KGEM_RELOC_SIZE(kgem)); 46403b705cfSriastradh return likely(kgem->nreloc + n <= KGEM_RELOC_SIZE(kgem)); 46503b705cfSriastradh} 46603b705cfSriastradh 46703b705cfSriastradhstatic inline bool kgem_check_exec(struct kgem *kgem, int n) 46803b705cfSriastradh{ 46903b705cfSriastradh assert(kgem->nexec <= KGEM_EXEC_SIZE(kgem)); 47003b705cfSriastradh return likely(kgem->nexec + n <= KGEM_EXEC_SIZE(kgem)); 47103b705cfSriastradh} 47203b705cfSriastradh 47303b705cfSriastradhstatic inline bool kgem_check_reloc_and_exec(struct kgem *kgem, int n) 47403b705cfSriastradh{ 47503b705cfSriastradh return kgem_check_reloc(kgem, n) && kgem_check_exec(kgem, n); 47603b705cfSriastradh} 47703b705cfSriastradh 47803b705cfSriastradhstatic inline bool kgem_check_batch_with_surfaces(struct kgem *kgem, 47903b705cfSriastradh int num_dwords, 48003b705cfSriastradh int num_surfaces) 48103b705cfSriastradh{ 48203b705cfSriastradh return (int)(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED) <= (int)(kgem->surface - num_surfaces*8) && 48303b705cfSriastradh kgem_check_reloc(kgem, num_surfaces) && 48403b705cfSriastradh kgem_check_exec(kgem, num_surfaces); 48503b705cfSriastradh} 48603b705cfSriastradh 48703b705cfSriastradhstatic inline uint32_t *kgem_get_batch(struct kgem *kgem) 48803b705cfSriastradh{ 48903b705cfSriastradh if (kgem->nreloc) { 49003b705cfSriastradh unsigned mode = kgem->mode; 49103b705cfSriastradh _kgem_submit(kgem); 49203b705cfSriastradh _kgem_set_mode(kgem, mode); 49303b705cfSriastradh } 49403b705cfSriastradh 49503b705cfSriastradh return kgem->batch + kgem->nbatch; 49603b705cfSriastradh} 49703b705cfSriastradh 49803b705cfSriastradhbool kgem_check_bo(struct kgem *kgem, ...) __attribute__((sentinel(0))); 49903b705cfSriastradhbool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo); 50003b705cfSriastradhbool kgem_check_many_bo_fenced(struct kgem *kgem, ...) __attribute__((sentinel(0))); 50103b705cfSriastradh 50203b705cfSriastradh#define KGEM_RELOC_FENCED 0x8000 50303b705cfSriastradhuint32_t kgem_add_reloc(struct kgem *kgem, 50403b705cfSriastradh uint32_t pos, 50503b705cfSriastradh struct kgem_bo *bo, 50603b705cfSriastradh uint32_t read_write_domains, 50703b705cfSriastradh uint32_t delta); 50842542f5fSchristosuint64_t kgem_add_reloc64(struct kgem *kgem, 50942542f5fSchristos uint32_t pos, 51042542f5fSchristos struct kgem_bo *bo, 51142542f5fSchristos uint32_t read_write_domains, 51242542f5fSchristos uint64_t delta); 51303b705cfSriastradh 51403b705cfSriastradhvoid *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo); 51503b705cfSriastradhvoid *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo); 51603b705cfSriastradhvoid *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo); 51713496ba1Ssnjvoid *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo); 51803b705cfSriastradhvoid kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo); 51903b705cfSriastradhvoid *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo); 52003b705cfSriastradhvoid *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo); 52103b705cfSriastradhvoid kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo); 52203b705cfSriastradhvoid kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write); 52303b705cfSriastradhuint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo); 52403b705cfSriastradh 52503b705cfSriastradhbool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo, 52603b705cfSriastradh const void *data, int length); 52703b705cfSriastradh 52803b705cfSriastradhint kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo); 52942542f5fSchristosvoid kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch, 53003b705cfSriastradh int *tile_width, int *tile_height, int *tile_size); 53103b705cfSriastradh 53203b705cfSriastradhstatic inline int __kgem_buffer_size(struct kgem_bo *bo) 53303b705cfSriastradh{ 53403b705cfSriastradh assert(bo->proxy != NULL); 53503b705cfSriastradh return bo->size.bytes; 53603b705cfSriastradh} 53703b705cfSriastradh 53803b705cfSriastradhstatic inline int __kgem_bo_size(struct kgem_bo *bo) 53903b705cfSriastradh{ 54003b705cfSriastradh assert(bo->proxy == NULL); 54103b705cfSriastradh return PAGE_SIZE * bo->size.pages.count; 54203b705cfSriastradh} 54303b705cfSriastradh 54442542f5fSchristosstatic inline int __kgem_bo_num_pages(struct kgem_bo *bo) 54542542f5fSchristos{ 54642542f5fSchristos assert(bo->proxy == NULL); 54742542f5fSchristos return bo->size.pages.count; 54842542f5fSchristos} 54942542f5fSchristos 55003b705cfSriastradhstatic inline int kgem_bo_size(struct kgem_bo *bo) 55103b705cfSriastradh{ 55203b705cfSriastradh if (bo->proxy) 55303b705cfSriastradh return __kgem_buffer_size(bo); 55403b705cfSriastradh else 55503b705cfSriastradh return __kgem_bo_size(bo); 55603b705cfSriastradh} 55703b705cfSriastradh 55803b705cfSriastradhstatic inline bool kgem_bo_blt_pitch_is_ok(struct kgem *kgem, 55903b705cfSriastradh struct kgem_bo *bo) 56003b705cfSriastradh{ 56103b705cfSriastradh int pitch = bo->pitch; 56213496ba1Ssnj 56313496ba1Ssnj if (kgem->gen >= 0100 && pitch & (1 << 4)) { /* bdw is broken */ 56413496ba1Ssnj DBG(("%s: can not blt to handle=%d, pitch=%d\n", 56513496ba1Ssnj __FUNCTION__, bo->handle, pitch)); 56613496ba1Ssnj return false; 56713496ba1Ssnj } 56813496ba1Ssnj 56903b705cfSriastradh if (kgem->gen >= 040 && bo->tiling) 57003b705cfSriastradh pitch /= 4; 57103b705cfSriastradh if (pitch > MAXSHORT) { 57203b705cfSriastradh DBG(("%s: can not blt to handle=%d, adjusted pitch=%d\n", 57303b705cfSriastradh __FUNCTION__, bo->handle, pitch)); 57403b705cfSriastradh return false; 57503b705cfSriastradh } 57603b705cfSriastradh 57703b705cfSriastradh return true; 57803b705cfSriastradh} 57903b705cfSriastradh 58003b705cfSriastradhstatic inline bool kgem_bo_can_blt(struct kgem *kgem, 58103b705cfSriastradh struct kgem_bo *bo) 58203b705cfSriastradh{ 58342542f5fSchristos assert(bo->refcnt); 58442542f5fSchristos 585fe8aea9eSmrg if (bo->tiling == I915_TILING_Y && !kgem->can_blt_y) { 58603b705cfSriastradh DBG(("%s: can not blt to handle=%d, tiling=Y\n", 58703b705cfSriastradh __FUNCTION__, bo->handle)); 58803b705cfSriastradh return false; 58903b705cfSriastradh } 59003b705cfSriastradh 591fe8aea9eSmrg if (kgem->gen >= 0100 && bo->proxy && bo->delta & 63) { 59213496ba1Ssnj DBG(("%s: can not blt to handle=%d, delta=%d\n", 59313496ba1Ssnj __FUNCTION__, bo->handle, bo->delta)); 59413496ba1Ssnj return false; 59513496ba1Ssnj } 59613496ba1Ssnj 59703b705cfSriastradh return kgem_bo_blt_pitch_is_ok(kgem, bo); 59803b705cfSriastradh} 59903b705cfSriastradh 600fe8aea9eSmrgvoid __kgem_bcs_set_tiling(struct kgem *kgem, 601fe8aea9eSmrg struct kgem_bo *src, 602fe8aea9eSmrg struct kgem_bo *dst); 603fe8aea9eSmrg 604fe8aea9eSmrginline static void kgem_bcs_set_tiling(struct kgem *kgem, 605fe8aea9eSmrg struct kgem_bo *src, 606fe8aea9eSmrg struct kgem_bo *dst) 607fe8aea9eSmrg{ 608fe8aea9eSmrg assert(kgem->mode == KGEM_BLT); 609fe8aea9eSmrg 610fe8aea9eSmrg if (!kgem->can_blt_y) 611fe8aea9eSmrg return; 612fe8aea9eSmrg 613fe8aea9eSmrg __kgem_bcs_set_tiling(kgem, src, dst); 614fe8aea9eSmrg} 615fe8aea9eSmrg 61603b705cfSriastradhstatic inline bool kgem_bo_is_snoop(struct kgem_bo *bo) 61703b705cfSriastradh{ 61803b705cfSriastradh assert(bo->refcnt); 61903b705cfSriastradh while (bo->proxy) 62003b705cfSriastradh bo = bo->proxy; 62103b705cfSriastradh return bo->snoop; 62203b705cfSriastradh} 62303b705cfSriastradh 62403b705cfSriastradhvoid kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo); 62542542f5fSchristosvoid kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b); 62603b705cfSriastradh 62703b705cfSriastradhbool __kgem_busy(struct kgem *kgem, int handle); 62803b705cfSriastradh 62942542f5fSchristosstatic inline void kgem_bo_mark_busy(struct kgem *kgem, struct kgem_bo *bo, int ring) 63003b705cfSriastradh{ 63142542f5fSchristos assert(bo->refcnt); 63242542f5fSchristos bo->needs_flush = true; 63342542f5fSchristos if (bo->rq) { 63442542f5fSchristos bo->rq = MAKE_REQUEST(RQ(bo->rq), ring); 63542542f5fSchristos } else { 63642542f5fSchristos bo->rq = MAKE_REQUEST(kgem, ring); 63742542f5fSchristos list_add(&bo->request, &kgem->flushing); 63842542f5fSchristos kgem->need_retire = true; 63942542f5fSchristos } 64003b705cfSriastradh} 64103b705cfSriastradh 642fe8aea9eSmrgstatic inline void __kgem_bo_clear_dirty(struct kgem_bo *bo) 64303b705cfSriastradh{ 64442542f5fSchristos DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); 64503b705cfSriastradh 64603b705cfSriastradh bo->domain = DOMAIN_NONE; 64703b705cfSriastradh bo->needs_flush = false; 64803b705cfSriastradh bo->gtt_dirty = false; 64903b705cfSriastradh} 65003b705cfSriastradh 651fe8aea9eSmrginline static void __kgem_bo_clear_busy(struct kgem_bo *bo) 652fe8aea9eSmrg{ 653fe8aea9eSmrg DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); 654fe8aea9eSmrg bo->rq = NULL; 655fe8aea9eSmrg list_del(&bo->request); 656fe8aea9eSmrg 657fe8aea9eSmrg __kgem_bo_clear_dirty(bo); 658fe8aea9eSmrg} 659fe8aea9eSmrg 66003b705cfSriastradhstatic inline bool kgem_bo_is_busy(struct kgem_bo *bo) 66103b705cfSriastradh{ 66203b705cfSriastradh DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, 66303b705cfSriastradh bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); 66403b705cfSriastradh assert(bo->refcnt); 66503b705cfSriastradh return bo->rq; 66603b705cfSriastradh} 66703b705cfSriastradh 668fe8aea9eSmrgbool __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo); 66903b705cfSriastradhstatic inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo) 67003b705cfSriastradh{ 67103b705cfSriastradh DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, 67203b705cfSriastradh bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); 67303b705cfSriastradh assert(bo->refcnt); 67403b705cfSriastradh 67503b705cfSriastradh if (bo->exec) 67603b705cfSriastradh return true; 67703b705cfSriastradh 678fe8aea9eSmrg if (bo->rq == NULL) 679fe8aea9eSmrg return false; 680fe8aea9eSmrg 681fe8aea9eSmrg if (__kgem_busy(kgem, bo->handle)) 682fe8aea9eSmrg return true; 68303b705cfSriastradh 684fe8aea9eSmrg return __kgem_retire_requests_upto(kgem, bo); 68503b705cfSriastradh} 68603b705cfSriastradh 68703b705cfSriastradhstatic inline bool kgem_bo_is_render(struct kgem_bo *bo) 68803b705cfSriastradh{ 68903b705cfSriastradh DBG(("%s: handle=%d, rq? %d [%d]\n", __FUNCTION__, 69042542f5fSchristos bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq))); 69103b705cfSriastradh assert(bo->refcnt); 692fe8aea9eSmrg return bo->rq && RQ_RING(bo->rq) != KGEM_BLT; 693fe8aea9eSmrg} 694fe8aea9eSmrg 695fe8aea9eSmrgstatic inline bool kgem_bo_is_blt(struct kgem_bo *bo) 696fe8aea9eSmrg{ 697fe8aea9eSmrg DBG(("%s: handle=%d, rq? %d\n", __FUNCTION__, 698fe8aea9eSmrg bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq))); 699fe8aea9eSmrg assert(bo->refcnt); 700fe8aea9eSmrg return RQ_RING(bo->rq) == KGEM_BLT; 70103b705cfSriastradh} 70203b705cfSriastradh 70303b705cfSriastradhstatic inline void kgem_bo_mark_unreusable(struct kgem_bo *bo) 70403b705cfSriastradh{ 70542542f5fSchristos assert(bo->refcnt); 70603b705cfSriastradh while (bo->proxy) { 70703b705cfSriastradh bo->flush = true; 70803b705cfSriastradh bo = bo->proxy; 70942542f5fSchristos assert(bo->refcnt); 71003b705cfSriastradh } 71103b705cfSriastradh bo->flush = true; 71203b705cfSriastradh bo->reusable = false; 71303b705cfSriastradh} 71403b705cfSriastradh 71503b705cfSriastradhstatic inline bool kgem_bo_is_dirty(struct kgem_bo *bo) 71603b705cfSriastradh{ 71703b705cfSriastradh if (bo == NULL) 71803b705cfSriastradh return false; 71903b705cfSriastradh 72003b705cfSriastradh assert(bo->refcnt); 72103b705cfSriastradh return bo->gpu_dirty; 72203b705cfSriastradh} 72303b705cfSriastradh 72403b705cfSriastradhstatic inline void kgem_bo_unclean(struct kgem *kgem, struct kgem_bo *bo) 72503b705cfSriastradh{ 72603b705cfSriastradh /* The bo is outside of our control, so presume it is written to */ 72703b705cfSriastradh bo->needs_flush = true; 72803b705cfSriastradh if (bo->rq == NULL) 72903b705cfSriastradh bo->rq = (void *)kgem; 73003b705cfSriastradh 73103b705cfSriastradh if (bo->domain != DOMAIN_GPU) 73203b705cfSriastradh bo->domain = DOMAIN_NONE; 73303b705cfSriastradh} 73403b705cfSriastradh 73503b705cfSriastradhstatic inline void __kgem_bo_mark_dirty(struct kgem_bo *bo) 73603b705cfSriastradh{ 73703b705cfSriastradh DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__, 73803b705cfSriastradh bo->handle, bo->proxy != NULL)); 73903b705cfSriastradh 74042542f5fSchristos assert(bo->refcnt); 74142542f5fSchristos assert(bo->exec); 74242542f5fSchristos assert(bo->rq); 74342542f5fSchristos 74403b705cfSriastradh bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE; 74503b705cfSriastradh bo->needs_flush = bo->gpu_dirty = true; 74603b705cfSriastradh list_move(&bo->request, &RQ(bo->rq)->buffers); 74703b705cfSriastradh} 74803b705cfSriastradh 74903b705cfSriastradhstatic inline void kgem_bo_mark_dirty(struct kgem_bo *bo) 75003b705cfSriastradh{ 75103b705cfSriastradh assert(bo->refcnt); 75203b705cfSriastradh do { 75303b705cfSriastradh assert(bo->exec); 75403b705cfSriastradh assert(bo->rq); 75503b705cfSriastradh 75603b705cfSriastradh if (bo->gpu_dirty) 75703b705cfSriastradh return; 75803b705cfSriastradh 75903b705cfSriastradh __kgem_bo_mark_dirty(bo); 76003b705cfSriastradh } while ((bo = bo->proxy)); 76103b705cfSriastradh} 76203b705cfSriastradh 76342542f5fSchristosstatic inline bool kgem_bo_mapped(struct kgem *kgem, struct kgem_bo *bo) 76442542f5fSchristos{ 76542542f5fSchristos DBG(("%s: handle=%d, map=%p:%p, tiling=%d, domain=%d\n", 76642542f5fSchristos __FUNCTION__, bo->handle, bo->map__gtt, bo->map__cpu, bo->tiling, bo->domain)); 76742542f5fSchristos assert(bo->proxy == NULL); 76842542f5fSchristos 76942542f5fSchristos if (bo->tiling == I915_TILING_NONE && (bo->domain == DOMAIN_CPU || kgem->has_llc)) 77042542f5fSchristos return bo->map__cpu != NULL; 77142542f5fSchristos 77213496ba1Ssnj if (bo->tiling == I915_TILING_NONE && bo->map__wc) 77313496ba1Ssnj return true; 77413496ba1Ssnj 77542542f5fSchristos return bo->map__gtt != NULL; 77642542f5fSchristos} 77742542f5fSchristos 77842542f5fSchristosstatic inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo) 77942542f5fSchristos{ 78013496ba1Ssnj DBG(("%s: handle=%d, map=%p:%p:%p, tiling=%d, domain=%d, offset=%ld\n", 78113496ba1Ssnj __FUNCTION__, bo->handle, bo->map__gtt, bo->map__wc, bo->map__cpu, bo->tiling, bo->domain, (long)bo->presumed_offset)); 78242542f5fSchristos 78342542f5fSchristos if (!bo->tiling && (kgem->has_llc || bo->domain == DOMAIN_CPU)) 78442542f5fSchristos return true; 78542542f5fSchristos 78642542f5fSchristos assert(bo->proxy == NULL); 78742542f5fSchristos 78842542f5fSchristos if (bo->map__gtt != NULL) 78942542f5fSchristos return true; 79042542f5fSchristos 79142542f5fSchristos if (kgem->gen == 021 && bo->tiling == I915_TILING_Y) 79242542f5fSchristos return false; 79342542f5fSchristos 79413496ba1Ssnj if (!bo->tiling && kgem->has_wc_mmap) 79513496ba1Ssnj return true; 79613496ba1Ssnj 79742542f5fSchristos return __kgem_bo_num_pages(bo) <= kgem->aperture_mappable / 4; 79842542f5fSchristos} 79942542f5fSchristos 80042542f5fSchristosstatic inline bool kgem_bo_can_map__cpu(struct kgem *kgem, 80142542f5fSchristos struct kgem_bo *bo, 80242542f5fSchristos bool write) 80342542f5fSchristos{ 80442542f5fSchristos DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); 80542542f5fSchristos assert(bo->refcnt); 80642542f5fSchristos 80742542f5fSchristos if (bo->purged || (bo->scanout && write)) { 80842542f5fSchristos DBG(("%s: no, writing to scanout? %d, or is stolen [inaccessible via CPU]? %d\n", 80942542f5fSchristos __FUNCTION__, bo->scanout && write, bo->purged)); 81042542f5fSchristos return false; 81142542f5fSchristos } 81242542f5fSchristos 81342542f5fSchristos if (kgem->has_llc) { 81442542f5fSchristos DBG(("%s: yes, has LLC and target is in LLC\n", __FUNCTION__)); 81542542f5fSchristos return true; 81642542f5fSchristos } 81742542f5fSchristos 81842542f5fSchristos DBG(("%s: non-LLC - CPU domain? %d, clean? %d\n", 81942542f5fSchristos __FUNCTION__, bo->domain == DOMAIN_CPU, !write || bo->exec == NULL)); 82042542f5fSchristos if (bo->domain != DOMAIN_CPU) 82142542f5fSchristos return false; 82242542f5fSchristos 82342542f5fSchristos return !write || bo->exec == NULL; 82442542f5fSchristos} 82542542f5fSchristos 82603b705cfSriastradh#define KGEM_BUFFER_WRITE 0x1 82703b705cfSriastradh#define KGEM_BUFFER_INPLACE 0x2 82803b705cfSriastradh#define KGEM_BUFFER_LAST 0x4 82903b705cfSriastradh 83003b705cfSriastradh#define KGEM_BUFFER_WRITE_INPLACE (KGEM_BUFFER_WRITE | KGEM_BUFFER_INPLACE) 83103b705cfSriastradh 83203b705cfSriastradhstruct kgem_bo *kgem_create_buffer(struct kgem *kgem, 83303b705cfSriastradh uint32_t size, uint32_t flags, 83403b705cfSriastradh void **ret); 83503b705cfSriastradhstruct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, 83603b705cfSriastradh int width, int height, int bpp, 83703b705cfSriastradh uint32_t flags, 83803b705cfSriastradh void **ret); 83903b705cfSriastradhbool kgem_buffer_is_inplace(struct kgem_bo *bo); 84003b705cfSriastradhvoid kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo); 84103b705cfSriastradh 84242542f5fSchristosint kgem_is_wedged(struct kgem *kgem); 84303b705cfSriastradhvoid kgem_throttle(struct kgem *kgem); 84403b705cfSriastradh#define MAX_INACTIVE_TIME 10 84503b705cfSriastradhbool kgem_expire_cache(struct kgem *kgem); 84642542f5fSchristosbool kgem_cleanup_cache(struct kgem *kgem); 84703b705cfSriastradh 84803b705cfSriastradhvoid kgem_clean_scanout_cache(struct kgem *kgem); 84903b705cfSriastradhvoid kgem_clean_large_cache(struct kgem *kgem); 85003b705cfSriastradh 85103b705cfSriastradh#if HAS_DEBUG_FULL 85203b705cfSriastradhvoid __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch); 85303b705cfSriastradh#else 85403b705cfSriastradhstatic inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch) 85503b705cfSriastradh{ 85603b705cfSriastradh (void)kgem; 85703b705cfSriastradh (void)nbatch; 85803b705cfSriastradh} 85903b705cfSriastradh#endif 86003b705cfSriastradh 86103b705cfSriastradhstatic inline void 86203b705cfSriastradhmemcpy_to_tiled_x(struct kgem *kgem, 86303b705cfSriastradh const void *src, void *dst, int bpp, 86403b705cfSriastradh int32_t src_stride, int32_t dst_stride, 86503b705cfSriastradh int16_t src_x, int16_t src_y, 86603b705cfSriastradh int16_t dst_x, int16_t dst_y, 86703b705cfSriastradh uint16_t width, uint16_t height) 86803b705cfSriastradh{ 86942542f5fSchristos assert(kgem->memcpy_to_tiled_x); 87042542f5fSchristos assert(src_x >= 0 && src_y >= 0); 87142542f5fSchristos assert(dst_x >= 0 && dst_y >= 0); 87242542f5fSchristos assert(8*src_stride >= (src_x+width) * bpp); 87342542f5fSchristos assert(8*dst_stride >= (dst_x+width) * bpp); 87403b705cfSriastradh return kgem->memcpy_to_tiled_x(src, dst, bpp, 87503b705cfSriastradh src_stride, dst_stride, 87603b705cfSriastradh src_x, src_y, 87703b705cfSriastradh dst_x, dst_y, 87803b705cfSriastradh width, height); 87903b705cfSriastradh} 88003b705cfSriastradh 88103b705cfSriastradhstatic inline void 88203b705cfSriastradhmemcpy_from_tiled_x(struct kgem *kgem, 88303b705cfSriastradh const void *src, void *dst, int bpp, 88403b705cfSriastradh int32_t src_stride, int32_t dst_stride, 88503b705cfSriastradh int16_t src_x, int16_t src_y, 88603b705cfSriastradh int16_t dst_x, int16_t dst_y, 88703b705cfSriastradh uint16_t width, uint16_t height) 88803b705cfSriastradh{ 88942542f5fSchristos assert(kgem->memcpy_from_tiled_x); 89042542f5fSchristos assert(src_x >= 0 && src_y >= 0); 89142542f5fSchristos assert(dst_x >= 0 && dst_y >= 0); 89242542f5fSchristos assert(8*src_stride >= (src_x+width) * bpp); 89342542f5fSchristos assert(8*dst_stride >= (dst_x+width) * bpp); 89403b705cfSriastradh return kgem->memcpy_from_tiled_x(src, dst, bpp, 89503b705cfSriastradh src_stride, dst_stride, 89603b705cfSriastradh src_x, src_y, 89703b705cfSriastradh dst_x, dst_y, 89803b705cfSriastradh width, height); 89903b705cfSriastradh} 90003b705cfSriastradh 901fe8aea9eSmrgvoid choose_memcpy_tiled_x(struct kgem *kgem, int swizzling, unsigned cpu); 90203b705cfSriastradh 90303b705cfSriastradh#endif /* KGEM_H */ 904