kgem.h revision 13496ba1
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) 4542542f5fSchristos#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring))) 4642542f5fSchristos 4703b705cfSriastradh struct drm_i915_gem_exec_object2 *exec; 4803b705cfSriastradh 4903b705cfSriastradh struct kgem_bo *proxy; 5003b705cfSriastradh 5103b705cfSriastradh struct list list; 5203b705cfSriastradh struct list request; 5303b705cfSriastradh struct list vma; 5403b705cfSriastradh 5542542f5fSchristos void *map__cpu; 5642542f5fSchristos void *map__gtt; 5713496ba1Ssnj void *map__wc; 5803b705cfSriastradh#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3)) 5903b705cfSriastradh 6003b705cfSriastradh struct kgem_bo_binding { 6103b705cfSriastradh struct kgem_bo_binding *next; 6203b705cfSriastradh uint32_t format; 6303b705cfSriastradh uint16_t offset; 6403b705cfSriastradh } binding; 6503b705cfSriastradh 6642542f5fSchristos uint64_t presumed_offset; 6703b705cfSriastradh uint32_t unique_id; 6803b705cfSriastradh uint32_t refcnt; 6903b705cfSriastradh uint32_t handle; 7003b705cfSriastradh uint32_t target_handle; 7103b705cfSriastradh uint32_t delta; 7242542f5fSchristos uint32_t active_scanout; 7303b705cfSriastradh union { 7403b705cfSriastradh struct { 7503b705cfSriastradh uint32_t count:27; 7603b705cfSriastradh#define PAGE_SIZE 4096 7703b705cfSriastradh uint32_t bucket:5; 7803b705cfSriastradh#define NUM_CACHE_BUCKETS 16 7903b705cfSriastradh#define MAX_CACHE_SIZE (1 << (NUM_CACHE_BUCKETS+12)) 8003b705cfSriastradh } pages; 8103b705cfSriastradh uint32_t bytes; 8203b705cfSriastradh } size; 8303b705cfSriastradh uint32_t pitch : 18; /* max 128k */ 8403b705cfSriastradh uint32_t tiling : 2; 8503b705cfSriastradh uint32_t reusable : 1; 8603b705cfSriastradh uint32_t gpu_dirty : 1; 8703b705cfSriastradh uint32_t gtt_dirty : 1; 8803b705cfSriastradh uint32_t domain : 2; 8903b705cfSriastradh uint32_t needs_flush : 1; 9003b705cfSriastradh uint32_t snoop : 1; 9103b705cfSriastradh uint32_t io : 1; 9203b705cfSriastradh uint32_t flush : 1; 9303b705cfSriastradh uint32_t scanout : 1; 9442542f5fSchristos uint32_t prime : 1; 9503b705cfSriastradh uint32_t purged : 1; 9603b705cfSriastradh}; 9703b705cfSriastradh#define DOMAIN_NONE 0 9803b705cfSriastradh#define DOMAIN_CPU 1 9903b705cfSriastradh#define DOMAIN_GTT 2 10003b705cfSriastradh#define DOMAIN_GPU 3 10103b705cfSriastradh 10203b705cfSriastradhstruct kgem_request { 10303b705cfSriastradh struct list list; 10403b705cfSriastradh struct kgem_bo *bo; 10503b705cfSriastradh struct list buffers; 10603b705cfSriastradh int ring; 10703b705cfSriastradh}; 10803b705cfSriastradh 10903b705cfSriastradhenum { 11003b705cfSriastradh MAP_GTT = 0, 11103b705cfSriastradh MAP_CPU, 11203b705cfSriastradh NUM_MAP_TYPES, 11303b705cfSriastradh}; 11403b705cfSriastradh 11503b705cfSriastradhstruct kgem { 11642542f5fSchristos unsigned wedged; 11713496ba1Ssnj int fd; 11803b705cfSriastradh unsigned gen; 11903b705cfSriastradh 12003b705cfSriastradh uint32_t unique_id; 12103b705cfSriastradh 12213496ba1Ssnj uint16_t nbatch; 12313496ba1Ssnj uint16_t surface; 12413496ba1Ssnj uint16_t nexec; 12513496ba1Ssnj uint16_t nreloc; 12613496ba1Ssnj uint16_t nreloc__self; 12713496ba1Ssnj uint16_t nfence; 12813496ba1Ssnj uint16_t batch_size; 12913496ba1Ssnj 13013496ba1Ssnj uint32_t *batch; 13113496ba1Ssnj 13203b705cfSriastradh enum kgem_mode { 13303b705cfSriastradh /* order matches I915_EXEC_RING ordering */ 13403b705cfSriastradh KGEM_NONE = 0, 13503b705cfSriastradh KGEM_RENDER, 13603b705cfSriastradh KGEM_BSD, 13703b705cfSriastradh KGEM_BLT, 13803b705cfSriastradh } mode, ring; 13903b705cfSriastradh 14003b705cfSriastradh struct list flushing; 14103b705cfSriastradh struct list large; 14203b705cfSriastradh struct list large_inactive; 14303b705cfSriastradh struct list active[NUM_CACHE_BUCKETS][3]; 14403b705cfSriastradh struct list inactive[NUM_CACHE_BUCKETS]; 14503b705cfSriastradh struct list pinned_batches[2]; 14603b705cfSriastradh struct list snoop; 14703b705cfSriastradh struct list scanout; 14803b705cfSriastradh struct list batch_buffers, active_buffers; 14903b705cfSriastradh 15003b705cfSriastradh struct list requests[2]; 15113496ba1Ssnj struct kgem_request *fence[2]; 15203b705cfSriastradh struct kgem_request *next_request; 15303b705cfSriastradh struct kgem_request static_request; 15403b705cfSriastradh 15503b705cfSriastradh struct { 15603b705cfSriastradh struct list inactive[NUM_CACHE_BUCKETS]; 15703b705cfSriastradh int16_t count; 15803b705cfSriastradh } vma[NUM_MAP_TYPES]; 15903b705cfSriastradh 16003b705cfSriastradh uint32_t batch_flags; 16103b705cfSriastradh uint32_t batch_flags_base; 16203b705cfSriastradh#define I915_EXEC_SECURE (1<<9) 16303b705cfSriastradh#define LOCAL_EXEC_OBJECT_WRITE (1<<2) 16403b705cfSriastradh 16503b705cfSriastradh uint32_t flush:1; 16603b705cfSriastradh uint32_t need_expire:1; 16703b705cfSriastradh uint32_t need_purge:1; 16803b705cfSriastradh uint32_t need_retire:1; 16903b705cfSriastradh uint32_t need_throttle:1; 17042542f5fSchristos uint32_t needs_semaphore:1; 17142542f5fSchristos uint32_t needs_reservation:1; 17203b705cfSriastradh uint32_t scanout_busy:1; 17303b705cfSriastradh uint32_t busy:1; 17403b705cfSriastradh 17503b705cfSriastradh uint32_t has_create2 :1; 17603b705cfSriastradh uint32_t has_userptr :1; 17703b705cfSriastradh uint32_t has_blt :1; 17803b705cfSriastradh uint32_t has_relaxed_fencing :1; 17903b705cfSriastradh uint32_t has_relaxed_delta :1; 18003b705cfSriastradh uint32_t has_semaphores :1; 18103b705cfSriastradh uint32_t has_secure_batches :1; 18203b705cfSriastradh uint32_t has_pinned_batches :1; 18303b705cfSriastradh uint32_t has_caching :1; 18403b705cfSriastradh uint32_t has_llc :1; 18503b705cfSriastradh uint32_t has_wt :1; 18603b705cfSriastradh uint32_t has_no_reloc :1; 18703b705cfSriastradh uint32_t has_handle_lut :1; 18813496ba1Ssnj uint32_t has_wc_mmap :1; 18903b705cfSriastradh 19003b705cfSriastradh uint32_t can_blt_cpu :1; 19142542f5fSchristos uint32_t can_render_y :1; 19203b705cfSriastradh 19303b705cfSriastradh uint16_t fence_max; 19403b705cfSriastradh uint16_t half_cpu_cache_pages; 19542542f5fSchristos uint32_t aperture_total, aperture_high, aperture_low, aperture_mappable, aperture_fenceable; 19642542f5fSchristos uint32_t aperture, aperture_fenced, aperture_max_fence; 19703b705cfSriastradh uint32_t max_upload_tile_size, max_copy_tile_size; 19803b705cfSriastradh uint32_t max_gpu_size, max_cpu_size; 19903b705cfSriastradh uint32_t large_object_size, max_object_size; 20003b705cfSriastradh uint32_t buffer_size; 20103b705cfSriastradh 20203b705cfSriastradh void (*context_switch)(struct kgem *kgem, int new_mode); 20303b705cfSriastradh void (*retire)(struct kgem *kgem); 20403b705cfSriastradh void (*expire)(struct kgem *kgem); 20503b705cfSriastradh 20603b705cfSriastradh void (*memcpy_to_tiled_x)(const void *src, void *dst, int bpp, 20703b705cfSriastradh int32_t src_stride, int32_t dst_stride, 20803b705cfSriastradh int16_t src_x, int16_t src_y, 20903b705cfSriastradh int16_t dst_x, int16_t dst_y, 21003b705cfSriastradh uint16_t width, uint16_t height); 21103b705cfSriastradh void (*memcpy_from_tiled_x)(const void *src, void *dst, int bpp, 21203b705cfSriastradh int32_t src_stride, int32_t dst_stride, 21303b705cfSriastradh int16_t src_x, int16_t src_y, 21403b705cfSriastradh int16_t dst_x, int16_t dst_y, 21503b705cfSriastradh uint16_t width, uint16_t height); 21603b705cfSriastradh 21713496ba1Ssnj struct kgem_bo *batch_bo; 21813496ba1Ssnj 21903b705cfSriastradh uint16_t reloc__self[256]; 22003b705cfSriastradh struct drm_i915_gem_exec_object2 exec[384] page_aligned; 22103b705cfSriastradh struct drm_i915_gem_relocation_entry reloc[8192] page_aligned; 22203b705cfSriastradh 22303b705cfSriastradh#ifdef DEBUG_MEMORY 22403b705cfSriastradh struct { 22503b705cfSriastradh int bo_allocs; 22603b705cfSriastradh size_t bo_bytes; 22703b705cfSriastradh } debug_memory; 22803b705cfSriastradh#endif 22903b705cfSriastradh}; 23003b705cfSriastradh 23103b705cfSriastradh#define KGEM_MAX_DEFERRED_VBO 16 23203b705cfSriastradh 23303b705cfSriastradh#define KGEM_BATCH_RESERVED 1 23403b705cfSriastradh#define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO) 23503b705cfSriastradh#define KGEM_EXEC_RESERVED (1+KGEM_MAX_DEFERRED_VBO) 23603b705cfSriastradh 23703b705cfSriastradh#ifndef ARRAY_SIZE 23803b705cfSriastradh#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 23903b705cfSriastradh#endif 24003b705cfSriastradh 24103b705cfSriastradh#define KGEM_BATCH_SIZE(K) ((K)->batch_size-KGEM_BATCH_RESERVED) 24203b705cfSriastradh#define KGEM_EXEC_SIZE(K) (int)(ARRAY_SIZE((K)->exec)-KGEM_EXEC_RESERVED) 24303b705cfSriastradh#define KGEM_RELOC_SIZE(K) (int)(ARRAY_SIZE((K)->reloc)-KGEM_RELOC_RESERVED) 24403b705cfSriastradh 24503b705cfSriastradhvoid kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen); 24603b705cfSriastradhvoid kgem_reset(struct kgem *kgem); 24703b705cfSriastradh 24803b705cfSriastradhstruct kgem_bo *kgem_create_map(struct kgem *kgem, 24903b705cfSriastradh void *ptr, uint32_t size, 25003b705cfSriastradh bool read_only); 25103b705cfSriastradh 25203b705cfSriastradhstruct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name); 25303b705cfSriastradhstruct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size); 25403b705cfSriastradhint kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo); 25503b705cfSriastradh 25603b705cfSriastradhstruct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags); 25703b705cfSriastradhstruct kgem_bo *kgem_create_proxy(struct kgem *kgem, 25803b705cfSriastradh struct kgem_bo *target, 25903b705cfSriastradh int offset, int length); 26003b705cfSriastradh 26103b705cfSriastradhstruct kgem_bo *kgem_upload_source_image(struct kgem *kgem, 26203b705cfSriastradh const void *data, 26303b705cfSriastradh const BoxRec *box, 26403b705cfSriastradh int stride, int bpp); 26503b705cfSriastradhvoid kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr); 26603b705cfSriastradh 26703b705cfSriastradhint kgem_choose_tiling(struct kgem *kgem, 26803b705cfSriastradh int tiling, int width, int height, int bpp); 26903b705cfSriastradhunsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth); 27003b705cfSriastradh#define KGEM_CAN_CREATE_GPU 0x1 27103b705cfSriastradh#define KGEM_CAN_CREATE_CPU 0x2 27203b705cfSriastradh#define KGEM_CAN_CREATE_LARGE 0x4 27303b705cfSriastradh#define KGEM_CAN_CREATE_GTT 0x8 27442542f5fSchristos#define KGEM_CAN_CREATE_TILED 0x10 27503b705cfSriastradh 27642542f5fSchristosbool kgem_check_surface_size(struct kgem *kgem, 27742542f5fSchristos uint32_t width, 27842542f5fSchristos uint32_t height, 27942542f5fSchristos uint32_t bpp, 28042542f5fSchristos uint32_t tiling, 28142542f5fSchristos uint32_t pitch, 28242542f5fSchristos uint32_t size); 28303b705cfSriastradh 28403b705cfSriastradhstruct kgem_bo * 28503b705cfSriastradhkgem_replace_bo(struct kgem *kgem, 28603b705cfSriastradh struct kgem_bo *src, 28703b705cfSriastradh uint32_t width, 28803b705cfSriastradh uint32_t height, 28903b705cfSriastradh uint32_t pitch, 29003b705cfSriastradh uint32_t bpp); 29103b705cfSriastradhenum { 29203b705cfSriastradh CREATE_EXACT = 0x1, 29303b705cfSriastradh CREATE_INACTIVE = 0x2, 29403b705cfSriastradh CREATE_CPU_MAP = 0x4, 29503b705cfSriastradh CREATE_GTT_MAP = 0x8, 29603b705cfSriastradh CREATE_SCANOUT = 0x10, 29703b705cfSriastradh CREATE_PRIME = 0x20, 29803b705cfSriastradh CREATE_TEMPORARY = 0x40, 29903b705cfSriastradh CREATE_CACHED = 0x80, 30013496ba1Ssnj CREATE_UNCACHED = 0x100, 30113496ba1Ssnj CREATE_NO_RETIRE = 0x200, 30213496ba1Ssnj CREATE_NO_THROTTLE = 0x400, 30303b705cfSriastradh}; 30403b705cfSriastradhstruct kgem_bo *kgem_create_2d(struct kgem *kgem, 30503b705cfSriastradh int width, 30603b705cfSriastradh int height, 30703b705cfSriastradh int bpp, 30803b705cfSriastradh int tiling, 30903b705cfSriastradh uint32_t flags); 31003b705cfSriastradhstruct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem, 31103b705cfSriastradh int width, 31203b705cfSriastradh int height, 31303b705cfSriastradh int bpp, 31403b705cfSriastradh uint32_t flags); 31503b705cfSriastradh 31642542f5fSchristosbool kgem_bo_convert_to_gpu(struct kgem *kgem, 31742542f5fSchristos struct kgem_bo *bo, 31842542f5fSchristos unsigned flags); 31942542f5fSchristos 32003b705cfSriastradhuint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format); 32103b705cfSriastradhvoid kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset); 32203b705cfSriastradh 32303b705cfSriastradhbool kgem_retire(struct kgem *kgem); 32442542f5fSchristosvoid kgem_retire__buffers(struct kgem *kgem); 32542542f5fSchristos 32642542f5fSchristosstatic inline bool kgem_bo_discard_cache(struct kgem_bo *bo, bool force) 32742542f5fSchristos{ 32842542f5fSchristos if (bo == NULL || bo->proxy == NULL) 32942542f5fSchristos return false; 33042542f5fSchristos 33142542f5fSchristos if (force) 33242542f5fSchristos return true; 33342542f5fSchristos 33442542f5fSchristos if (bo->proxy->rq) 33542542f5fSchristos return false; 33642542f5fSchristos 33742542f5fSchristos return bo->snoop; 33842542f5fSchristos} 33903b705cfSriastradh 34003b705cfSriastradhbool __kgem_ring_is_idle(struct kgem *kgem, int ring); 34103b705cfSriastradhstatic inline bool kgem_ring_is_idle(struct kgem *kgem, int ring) 34203b705cfSriastradh{ 34303b705cfSriastradh ring = ring == KGEM_BLT; 34403b705cfSriastradh 34503b705cfSriastradh if (list_is_empty(&kgem->requests[ring])) 34603b705cfSriastradh return true; 34703b705cfSriastradh 34803b705cfSriastradh return __kgem_ring_is_idle(kgem, ring); 34903b705cfSriastradh} 35003b705cfSriastradh 35103b705cfSriastradhstatic inline bool kgem_is_idle(struct kgem *kgem) 35203b705cfSriastradh{ 35303b705cfSriastradh if (!kgem->need_retire) 35403b705cfSriastradh return true; 35503b705cfSriastradh 35603b705cfSriastradh return kgem_ring_is_idle(kgem, kgem->ring); 35703b705cfSriastradh} 35803b705cfSriastradh 35903b705cfSriastradhstatic inline bool __kgem_ring_empty(struct kgem *kgem) 36003b705cfSriastradh{ 36103b705cfSriastradh return list_is_empty(&kgem->requests[kgem->ring == KGEM_BLT]); 36203b705cfSriastradh} 36303b705cfSriastradh 36403b705cfSriastradhvoid _kgem_submit(struct kgem *kgem); 36503b705cfSriastradhstatic inline void kgem_submit(struct kgem *kgem) 36603b705cfSriastradh{ 36703b705cfSriastradh if (kgem->nbatch) 36803b705cfSriastradh _kgem_submit(kgem); 36903b705cfSriastradh} 37003b705cfSriastradh 37103b705cfSriastradhstatic inline void kgem_bo_submit(struct kgem *kgem, struct kgem_bo *bo) 37203b705cfSriastradh{ 37342542f5fSchristos if (bo->exec == NULL) 37442542f5fSchristos return; 37542542f5fSchristos 37642542f5fSchristos assert(bo->refcnt); 37742542f5fSchristos _kgem_submit(kgem); 37803b705cfSriastradh} 37903b705cfSriastradh 38003b705cfSriastradhvoid kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo); 38103b705cfSriastradh 38203b705cfSriastradhstatic inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo) 38303b705cfSriastradh{ 38403b705cfSriastradh assert(bo->refcnt); 38503b705cfSriastradh bo->refcnt++; 38603b705cfSriastradh return bo; 38703b705cfSriastradh} 38803b705cfSriastradh 38903b705cfSriastradhvoid _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo); 39003b705cfSriastradhstatic inline void kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) 39103b705cfSriastradh{ 39203b705cfSriastradh assert(bo->refcnt); 39303b705cfSriastradh if (--bo->refcnt == 0) 39403b705cfSriastradh _kgem_bo_destroy(kgem, bo); 39503b705cfSriastradh} 39603b705cfSriastradh 39703b705cfSriastradhvoid kgem_clear_dirty(struct kgem *kgem); 39803b705cfSriastradh 39903b705cfSriastradhstatic inline void kgem_set_mode(struct kgem *kgem, 40003b705cfSriastradh enum kgem_mode mode, 40103b705cfSriastradh struct kgem_bo *bo) 40203b705cfSriastradh{ 40303b705cfSriastradh assert(!kgem->wedged); 40403b705cfSriastradh 40503b705cfSriastradh#if DEBUG_FLUSH_BATCH 40603b705cfSriastradh kgem_submit(kgem); 40703b705cfSriastradh#endif 40803b705cfSriastradh 40942542f5fSchristos if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) { 41042542f5fSchristos DBG(("%s: flushing before new bo\n", __FUNCTION__)); 41103b705cfSriastradh _kgem_submit(kgem); 41242542f5fSchristos } 41303b705cfSriastradh 41403b705cfSriastradh if (kgem->mode == mode) 41503b705cfSriastradh return; 41603b705cfSriastradh 41703b705cfSriastradh kgem->context_switch(kgem, mode); 41803b705cfSriastradh kgem->mode = mode; 41903b705cfSriastradh} 42003b705cfSriastradh 42103b705cfSriastradhstatic inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode) 42203b705cfSriastradh{ 42303b705cfSriastradh assert(kgem->mode == KGEM_NONE); 42403b705cfSriastradh assert(kgem->nbatch == 0); 42503b705cfSriastradh assert(!kgem->wedged); 42603b705cfSriastradh kgem->context_switch(kgem, mode); 42703b705cfSriastradh kgem->mode = mode; 42803b705cfSriastradh} 42903b705cfSriastradh 43013496ba1Ssnjstatic inline int kgem_batch_space(struct kgem *kgem) 43113496ba1Ssnj{ 43213496ba1Ssnj int rem = kgem->surface - kgem->nbatch; 43313496ba1Ssnj assert(rem > 0); 43413496ba1Ssnj return rem - KGEM_BATCH_RESERVED; 43513496ba1Ssnj} 43613496ba1Ssnj 43703b705cfSriastradhstatic inline bool kgem_check_batch(struct kgem *kgem, int num_dwords) 43803b705cfSriastradh{ 43903b705cfSriastradh assert(num_dwords > 0); 44003b705cfSriastradh assert(kgem->nbatch < kgem->surface); 44103b705cfSriastradh assert(kgem->surface <= kgem->batch_size); 44203b705cfSriastradh return likely(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED <= kgem->surface); 44303b705cfSriastradh} 44403b705cfSriastradh 44503b705cfSriastradhstatic inline bool kgem_check_reloc(struct kgem *kgem, int n) 44603b705cfSriastradh{ 44703b705cfSriastradh assert(kgem->nreloc <= KGEM_RELOC_SIZE(kgem)); 44803b705cfSriastradh return likely(kgem->nreloc + n <= KGEM_RELOC_SIZE(kgem)); 44903b705cfSriastradh} 45003b705cfSriastradh 45103b705cfSriastradhstatic inline bool kgem_check_exec(struct kgem *kgem, int n) 45203b705cfSriastradh{ 45303b705cfSriastradh assert(kgem->nexec <= KGEM_EXEC_SIZE(kgem)); 45403b705cfSriastradh return likely(kgem->nexec + n <= KGEM_EXEC_SIZE(kgem)); 45503b705cfSriastradh} 45603b705cfSriastradh 45703b705cfSriastradhstatic inline bool kgem_check_reloc_and_exec(struct kgem *kgem, int n) 45803b705cfSriastradh{ 45903b705cfSriastradh return kgem_check_reloc(kgem, n) && kgem_check_exec(kgem, n); 46003b705cfSriastradh} 46103b705cfSriastradh 46203b705cfSriastradhstatic inline bool kgem_check_batch_with_surfaces(struct kgem *kgem, 46303b705cfSriastradh int num_dwords, 46403b705cfSriastradh int num_surfaces) 46503b705cfSriastradh{ 46603b705cfSriastradh return (int)(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED) <= (int)(kgem->surface - num_surfaces*8) && 46703b705cfSriastradh kgem_check_reloc(kgem, num_surfaces) && 46803b705cfSriastradh kgem_check_exec(kgem, num_surfaces); 46903b705cfSriastradh} 47003b705cfSriastradh 47103b705cfSriastradhstatic inline uint32_t *kgem_get_batch(struct kgem *kgem) 47203b705cfSriastradh{ 47303b705cfSriastradh if (kgem->nreloc) { 47403b705cfSriastradh unsigned mode = kgem->mode; 47503b705cfSriastradh _kgem_submit(kgem); 47603b705cfSriastradh _kgem_set_mode(kgem, mode); 47703b705cfSriastradh } 47803b705cfSriastradh 47903b705cfSriastradh return kgem->batch + kgem->nbatch; 48003b705cfSriastradh} 48103b705cfSriastradh 48203b705cfSriastradhbool kgem_check_bo(struct kgem *kgem, ...) __attribute__((sentinel(0))); 48303b705cfSriastradhbool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo); 48403b705cfSriastradhbool kgem_check_many_bo_fenced(struct kgem *kgem, ...) __attribute__((sentinel(0))); 48503b705cfSriastradh 48603b705cfSriastradh#define KGEM_RELOC_FENCED 0x8000 48703b705cfSriastradhuint32_t kgem_add_reloc(struct kgem *kgem, 48803b705cfSriastradh uint32_t pos, 48903b705cfSriastradh struct kgem_bo *bo, 49003b705cfSriastradh uint32_t read_write_domains, 49103b705cfSriastradh uint32_t delta); 49242542f5fSchristosuint64_t kgem_add_reloc64(struct kgem *kgem, 49342542f5fSchristos uint32_t pos, 49442542f5fSchristos struct kgem_bo *bo, 49542542f5fSchristos uint32_t read_write_domains, 49642542f5fSchristos uint64_t delta); 49703b705cfSriastradh 49803b705cfSriastradhvoid *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo); 49903b705cfSriastradhvoid *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo); 50003b705cfSriastradhvoid *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo); 50113496ba1Ssnjvoid *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo); 50203b705cfSriastradhvoid kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo); 50303b705cfSriastradhvoid *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo); 50403b705cfSriastradhvoid *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo); 50503b705cfSriastradhvoid kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo); 50603b705cfSriastradhvoid kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write); 50703b705cfSriastradhuint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo); 50803b705cfSriastradh 50903b705cfSriastradhbool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo, 51003b705cfSriastradh const void *data, int length); 51103b705cfSriastradh 51203b705cfSriastradhint kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo); 51342542f5fSchristosvoid kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch, 51403b705cfSriastradh int *tile_width, int *tile_height, int *tile_size); 51503b705cfSriastradh 51603b705cfSriastradhstatic inline int __kgem_buffer_size(struct kgem_bo *bo) 51703b705cfSriastradh{ 51803b705cfSriastradh assert(bo->proxy != NULL); 51903b705cfSriastradh return bo->size.bytes; 52003b705cfSriastradh} 52103b705cfSriastradh 52203b705cfSriastradhstatic inline int __kgem_bo_size(struct kgem_bo *bo) 52303b705cfSriastradh{ 52403b705cfSriastradh assert(bo->proxy == NULL); 52503b705cfSriastradh return PAGE_SIZE * bo->size.pages.count; 52603b705cfSriastradh} 52703b705cfSriastradh 52842542f5fSchristosstatic inline int __kgem_bo_num_pages(struct kgem_bo *bo) 52942542f5fSchristos{ 53042542f5fSchristos assert(bo->proxy == NULL); 53142542f5fSchristos return bo->size.pages.count; 53242542f5fSchristos} 53342542f5fSchristos 53403b705cfSriastradhstatic inline int kgem_bo_size(struct kgem_bo *bo) 53503b705cfSriastradh{ 53603b705cfSriastradh if (bo->proxy) 53703b705cfSriastradh return __kgem_buffer_size(bo); 53803b705cfSriastradh else 53903b705cfSriastradh return __kgem_bo_size(bo); 54003b705cfSriastradh} 54103b705cfSriastradh 54203b705cfSriastradhstatic inline bool kgem_bo_blt_pitch_is_ok(struct kgem *kgem, 54303b705cfSriastradh struct kgem_bo *bo) 54403b705cfSriastradh{ 54503b705cfSriastradh int pitch = bo->pitch; 54613496ba1Ssnj 54713496ba1Ssnj if (kgem->gen >= 0100 && pitch & (1 << 4)) { /* bdw is broken */ 54813496ba1Ssnj DBG(("%s: can not blt to handle=%d, pitch=%d\n", 54913496ba1Ssnj __FUNCTION__, bo->handle, pitch)); 55013496ba1Ssnj return false; 55113496ba1Ssnj } 55213496ba1Ssnj 55303b705cfSriastradh if (kgem->gen >= 040 && bo->tiling) 55403b705cfSriastradh pitch /= 4; 55503b705cfSriastradh if (pitch > MAXSHORT) { 55603b705cfSriastradh DBG(("%s: can not blt to handle=%d, adjusted pitch=%d\n", 55703b705cfSriastradh __FUNCTION__, bo->handle, pitch)); 55803b705cfSriastradh return false; 55903b705cfSriastradh } 56003b705cfSriastradh 56103b705cfSriastradh return true; 56203b705cfSriastradh} 56303b705cfSriastradh 56403b705cfSriastradhstatic inline bool kgem_bo_can_blt(struct kgem *kgem, 56503b705cfSriastradh struct kgem_bo *bo) 56603b705cfSriastradh{ 56742542f5fSchristos assert(bo->refcnt); 56842542f5fSchristos 56903b705cfSriastradh if (bo->tiling == I915_TILING_Y) { 57003b705cfSriastradh DBG(("%s: can not blt to handle=%d, tiling=Y\n", 57103b705cfSriastradh __FUNCTION__, bo->handle)); 57203b705cfSriastradh return false; 57303b705cfSriastradh } 57403b705cfSriastradh 57513496ba1Ssnj if (kgem->gen >= 0100 && bo->proxy && bo->delta & (1 << 4)) { 57613496ba1Ssnj DBG(("%s: can not blt to handle=%d, delta=%d\n", 57713496ba1Ssnj __FUNCTION__, bo->handle, bo->delta)); 57813496ba1Ssnj return false; 57913496ba1Ssnj } 58013496ba1Ssnj 58103b705cfSriastradh return kgem_bo_blt_pitch_is_ok(kgem, bo); 58203b705cfSriastradh} 58303b705cfSriastradh 58403b705cfSriastradhstatic inline bool kgem_bo_is_snoop(struct kgem_bo *bo) 58503b705cfSriastradh{ 58603b705cfSriastradh assert(bo->refcnt); 58703b705cfSriastradh while (bo->proxy) 58803b705cfSriastradh bo = bo->proxy; 58903b705cfSriastradh return bo->snoop; 59003b705cfSriastradh} 59103b705cfSriastradh 59203b705cfSriastradhvoid kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo); 59342542f5fSchristosvoid kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b); 59403b705cfSriastradh 59503b705cfSriastradhbool __kgem_busy(struct kgem *kgem, int handle); 59603b705cfSriastradh 59742542f5fSchristosstatic inline void kgem_bo_mark_busy(struct kgem *kgem, struct kgem_bo *bo, int ring) 59803b705cfSriastradh{ 59942542f5fSchristos assert(bo->refcnt); 60042542f5fSchristos bo->needs_flush = true; 60142542f5fSchristos if (bo->rq) { 60242542f5fSchristos bo->rq = MAKE_REQUEST(RQ(bo->rq), ring); 60342542f5fSchristos } else { 60442542f5fSchristos bo->rq = MAKE_REQUEST(kgem, ring); 60542542f5fSchristos list_add(&bo->request, &kgem->flushing); 60642542f5fSchristos kgem->need_retire = true; 60742542f5fSchristos } 60803b705cfSriastradh} 60903b705cfSriastradh 61003b705cfSriastradhinline static void __kgem_bo_clear_busy(struct kgem_bo *bo) 61103b705cfSriastradh{ 61242542f5fSchristos DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); 61303b705cfSriastradh bo->rq = NULL; 61403b705cfSriastradh list_del(&bo->request); 61503b705cfSriastradh 61603b705cfSriastradh bo->domain = DOMAIN_NONE; 61703b705cfSriastradh bo->needs_flush = false; 61803b705cfSriastradh bo->gtt_dirty = false; 61903b705cfSriastradh} 62003b705cfSriastradh 62103b705cfSriastradhstatic inline bool kgem_bo_is_busy(struct kgem_bo *bo) 62203b705cfSriastradh{ 62303b705cfSriastradh DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, 62403b705cfSriastradh bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); 62503b705cfSriastradh assert(bo->refcnt); 62603b705cfSriastradh return bo->rq; 62703b705cfSriastradh} 62803b705cfSriastradh 62913496ba1Ssnjvoid __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo); 63003b705cfSriastradhstatic inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo) 63103b705cfSriastradh{ 63203b705cfSriastradh DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, 63303b705cfSriastradh bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); 63403b705cfSriastradh assert(bo->refcnt); 63503b705cfSriastradh 63603b705cfSriastradh if (bo->exec) 63703b705cfSriastradh return true; 63803b705cfSriastradh 63913496ba1Ssnj if (bo->rq && !__kgem_busy(kgem, bo->handle)) { 64013496ba1Ssnj __kgem_retire_requests_upto(kgem, bo); 64113496ba1Ssnj assert(list_is_empty(&bo->request)); 64213496ba1Ssnj assert(bo->rq == NULL); 64313496ba1Ssnj assert(bo->domain == DOMAIN_NONE); 64413496ba1Ssnj } 64503b705cfSriastradh 64603b705cfSriastradh return kgem_bo_is_busy(bo); 64703b705cfSriastradh} 64803b705cfSriastradh 64903b705cfSriastradhstatic inline bool kgem_bo_is_render(struct kgem_bo *bo) 65003b705cfSriastradh{ 65103b705cfSriastradh DBG(("%s: handle=%d, rq? %d [%d]\n", __FUNCTION__, 65242542f5fSchristos bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq))); 65303b705cfSriastradh assert(bo->refcnt); 65403b705cfSriastradh return bo->rq && RQ_RING(bo->rq) == I915_EXEC_RENDER; 65503b705cfSriastradh} 65603b705cfSriastradh 65703b705cfSriastradhstatic inline void kgem_bo_mark_unreusable(struct kgem_bo *bo) 65803b705cfSriastradh{ 65942542f5fSchristos assert(bo->refcnt); 66003b705cfSriastradh while (bo->proxy) { 66103b705cfSriastradh bo->flush = true; 66203b705cfSriastradh bo = bo->proxy; 66342542f5fSchristos assert(bo->refcnt); 66403b705cfSriastradh } 66503b705cfSriastradh bo->flush = true; 66603b705cfSriastradh bo->reusable = false; 66703b705cfSriastradh} 66803b705cfSriastradh 66903b705cfSriastradhstatic inline bool kgem_bo_is_dirty(struct kgem_bo *bo) 67003b705cfSriastradh{ 67103b705cfSriastradh if (bo == NULL) 67203b705cfSriastradh return false; 67303b705cfSriastradh 67403b705cfSriastradh assert(bo->refcnt); 67503b705cfSriastradh return bo->gpu_dirty; 67603b705cfSriastradh} 67703b705cfSriastradh 67803b705cfSriastradhstatic inline void kgem_bo_unclean(struct kgem *kgem, struct kgem_bo *bo) 67903b705cfSriastradh{ 68003b705cfSriastradh /* The bo is outside of our control, so presume it is written to */ 68103b705cfSriastradh bo->needs_flush = true; 68203b705cfSriastradh if (bo->rq == NULL) 68303b705cfSriastradh bo->rq = (void *)kgem; 68403b705cfSriastradh 68503b705cfSriastradh if (bo->domain != DOMAIN_GPU) 68603b705cfSriastradh bo->domain = DOMAIN_NONE; 68703b705cfSriastradh} 68803b705cfSriastradh 68903b705cfSriastradhstatic inline void __kgem_bo_mark_dirty(struct kgem_bo *bo) 69003b705cfSriastradh{ 69103b705cfSriastradh DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__, 69203b705cfSriastradh bo->handle, bo->proxy != NULL)); 69303b705cfSriastradh 69442542f5fSchristos assert(bo->refcnt); 69542542f5fSchristos assert(bo->exec); 69642542f5fSchristos assert(bo->rq); 69742542f5fSchristos 69803b705cfSriastradh bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE; 69903b705cfSriastradh bo->needs_flush = bo->gpu_dirty = true; 70003b705cfSriastradh list_move(&bo->request, &RQ(bo->rq)->buffers); 70103b705cfSriastradh} 70203b705cfSriastradh 70303b705cfSriastradhstatic inline void kgem_bo_mark_dirty(struct kgem_bo *bo) 70403b705cfSriastradh{ 70503b705cfSriastradh assert(bo->refcnt); 70603b705cfSriastradh do { 70703b705cfSriastradh assert(bo->exec); 70803b705cfSriastradh assert(bo->rq); 70903b705cfSriastradh 71003b705cfSriastradh if (bo->gpu_dirty) 71103b705cfSriastradh return; 71203b705cfSriastradh 71303b705cfSriastradh __kgem_bo_mark_dirty(bo); 71403b705cfSriastradh } while ((bo = bo->proxy)); 71503b705cfSriastradh} 71603b705cfSriastradh 71742542f5fSchristosstatic inline bool kgem_bo_mapped(struct kgem *kgem, struct kgem_bo *bo) 71842542f5fSchristos{ 71942542f5fSchristos DBG(("%s: handle=%d, map=%p:%p, tiling=%d, domain=%d\n", 72042542f5fSchristos __FUNCTION__, bo->handle, bo->map__gtt, bo->map__cpu, bo->tiling, bo->domain)); 72142542f5fSchristos assert(bo->proxy == NULL); 72242542f5fSchristos 72342542f5fSchristos if (bo->tiling == I915_TILING_NONE && (bo->domain == DOMAIN_CPU || kgem->has_llc)) 72442542f5fSchristos return bo->map__cpu != NULL; 72542542f5fSchristos 72613496ba1Ssnj if (bo->tiling == I915_TILING_NONE && bo->map__wc) 72713496ba1Ssnj return true; 72813496ba1Ssnj 72942542f5fSchristos return bo->map__gtt != NULL; 73042542f5fSchristos} 73142542f5fSchristos 73242542f5fSchristosstatic inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo) 73342542f5fSchristos{ 73413496ba1Ssnj DBG(("%s: handle=%d, map=%p:%p:%p, tiling=%d, domain=%d, offset=%ld\n", 73513496ba1Ssnj __FUNCTION__, bo->handle, bo->map__gtt, bo->map__wc, bo->map__cpu, bo->tiling, bo->domain, (long)bo->presumed_offset)); 73642542f5fSchristos 73742542f5fSchristos if (!bo->tiling && (kgem->has_llc || bo->domain == DOMAIN_CPU)) 73842542f5fSchristos return true; 73942542f5fSchristos 74042542f5fSchristos assert(bo->proxy == NULL); 74142542f5fSchristos 74242542f5fSchristos if (bo->map__gtt != NULL) 74342542f5fSchristos return true; 74442542f5fSchristos 74542542f5fSchristos if (kgem->gen == 021 && bo->tiling == I915_TILING_Y) 74642542f5fSchristos return false; 74742542f5fSchristos 74813496ba1Ssnj if (!bo->tiling && kgem->has_wc_mmap) 74913496ba1Ssnj return true; 75013496ba1Ssnj 75142542f5fSchristos return __kgem_bo_num_pages(bo) <= kgem->aperture_mappable / 4; 75242542f5fSchristos} 75342542f5fSchristos 75442542f5fSchristosstatic inline bool kgem_bo_can_map__cpu(struct kgem *kgem, 75542542f5fSchristos struct kgem_bo *bo, 75642542f5fSchristos bool write) 75742542f5fSchristos{ 75842542f5fSchristos DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); 75942542f5fSchristos assert(bo->refcnt); 76042542f5fSchristos 76142542f5fSchristos if (bo->purged || (bo->scanout && write)) { 76242542f5fSchristos DBG(("%s: no, writing to scanout? %d, or is stolen [inaccessible via CPU]? %d\n", 76342542f5fSchristos __FUNCTION__, bo->scanout && write, bo->purged)); 76442542f5fSchristos return false; 76542542f5fSchristos } 76642542f5fSchristos 76742542f5fSchristos if (kgem->has_llc) { 76842542f5fSchristos DBG(("%s: yes, has LLC and target is in LLC\n", __FUNCTION__)); 76942542f5fSchristos return true; 77042542f5fSchristos } 77142542f5fSchristos 77242542f5fSchristos DBG(("%s: non-LLC - CPU domain? %d, clean? %d\n", 77342542f5fSchristos __FUNCTION__, bo->domain == DOMAIN_CPU, !write || bo->exec == NULL)); 77442542f5fSchristos if (bo->domain != DOMAIN_CPU) 77542542f5fSchristos return false; 77642542f5fSchristos 77742542f5fSchristos return !write || bo->exec == NULL; 77842542f5fSchristos} 77942542f5fSchristos 78003b705cfSriastradh#define KGEM_BUFFER_WRITE 0x1 78103b705cfSriastradh#define KGEM_BUFFER_INPLACE 0x2 78203b705cfSriastradh#define KGEM_BUFFER_LAST 0x4 78303b705cfSriastradh 78403b705cfSriastradh#define KGEM_BUFFER_WRITE_INPLACE (KGEM_BUFFER_WRITE | KGEM_BUFFER_INPLACE) 78503b705cfSriastradh 78603b705cfSriastradhstruct kgem_bo *kgem_create_buffer(struct kgem *kgem, 78703b705cfSriastradh uint32_t size, uint32_t flags, 78803b705cfSriastradh void **ret); 78903b705cfSriastradhstruct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, 79003b705cfSriastradh int width, int height, int bpp, 79103b705cfSriastradh uint32_t flags, 79203b705cfSriastradh void **ret); 79303b705cfSriastradhbool kgem_buffer_is_inplace(struct kgem_bo *bo); 79403b705cfSriastradhvoid kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo); 79503b705cfSriastradh 79642542f5fSchristosint kgem_is_wedged(struct kgem *kgem); 79703b705cfSriastradhvoid kgem_throttle(struct kgem *kgem); 79803b705cfSriastradh#define MAX_INACTIVE_TIME 10 79903b705cfSriastradhbool kgem_expire_cache(struct kgem *kgem); 80042542f5fSchristosbool kgem_cleanup_cache(struct kgem *kgem); 80103b705cfSriastradh 80203b705cfSriastradhvoid kgem_clean_scanout_cache(struct kgem *kgem); 80303b705cfSriastradhvoid kgem_clean_large_cache(struct kgem *kgem); 80403b705cfSriastradh 80503b705cfSriastradh#if HAS_DEBUG_FULL 80603b705cfSriastradhvoid __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch); 80703b705cfSriastradh#else 80803b705cfSriastradhstatic inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch) 80903b705cfSriastradh{ 81003b705cfSriastradh (void)kgem; 81103b705cfSriastradh (void)nbatch; 81203b705cfSriastradh} 81303b705cfSriastradh#endif 81403b705cfSriastradh 81503b705cfSriastradhstatic inline void 81603b705cfSriastradhmemcpy_to_tiled_x(struct kgem *kgem, 81703b705cfSriastradh const void *src, void *dst, int bpp, 81803b705cfSriastradh int32_t src_stride, int32_t dst_stride, 81903b705cfSriastradh int16_t src_x, int16_t src_y, 82003b705cfSriastradh int16_t dst_x, int16_t dst_y, 82103b705cfSriastradh uint16_t width, uint16_t height) 82203b705cfSriastradh{ 82342542f5fSchristos assert(kgem->memcpy_to_tiled_x); 82442542f5fSchristos assert(src_x >= 0 && src_y >= 0); 82542542f5fSchristos assert(dst_x >= 0 && dst_y >= 0); 82642542f5fSchristos assert(8*src_stride >= (src_x+width) * bpp); 82742542f5fSchristos assert(8*dst_stride >= (dst_x+width) * bpp); 82803b705cfSriastradh return kgem->memcpy_to_tiled_x(src, dst, bpp, 82903b705cfSriastradh src_stride, dst_stride, 83003b705cfSriastradh src_x, src_y, 83103b705cfSriastradh dst_x, dst_y, 83203b705cfSriastradh width, height); 83303b705cfSriastradh} 83403b705cfSriastradh 83503b705cfSriastradhstatic inline void 83603b705cfSriastradhmemcpy_from_tiled_x(struct kgem *kgem, 83703b705cfSriastradh const void *src, void *dst, int bpp, 83803b705cfSriastradh int32_t src_stride, int32_t dst_stride, 83903b705cfSriastradh int16_t src_x, int16_t src_y, 84003b705cfSriastradh int16_t dst_x, int16_t dst_y, 84103b705cfSriastradh uint16_t width, uint16_t height) 84203b705cfSriastradh{ 84342542f5fSchristos assert(kgem->memcpy_from_tiled_x); 84442542f5fSchristos assert(src_x >= 0 && src_y >= 0); 84542542f5fSchristos assert(dst_x >= 0 && dst_y >= 0); 84642542f5fSchristos assert(8*src_stride >= (src_x+width) * bpp); 84742542f5fSchristos assert(8*dst_stride >= (dst_x+width) * bpp); 84803b705cfSriastradh return kgem->memcpy_from_tiled_x(src, dst, bpp, 84903b705cfSriastradh src_stride, dst_stride, 85003b705cfSriastradh src_x, src_y, 85103b705cfSriastradh dst_x, dst_y, 85203b705cfSriastradh width, height); 85303b705cfSriastradh} 85403b705cfSriastradh 85503b705cfSriastradhvoid choose_memcpy_tiled_x(struct kgem *kgem, int swizzling); 85603b705cfSriastradh 85703b705cfSriastradh#endif /* KGEM_H */ 858