Home | History | Annotate | Download | only in intel
      1 /*
      2  * Copyright  2007 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *    Eric Anholt <eric (at) anholt.net>
     25  *
     26  */
     27 
     28 #include <string.h>
     29 #include <stdlib.h>
     30 #include <stdint.h>
     31 #include <assert.h>
     32 #include <errno.h>
     33 #include <drm.h>
     34 #include <i915_drm.h>
     35 #ifndef __ANDROID__
     36 #include <pciaccess.h>
     37 #endif
     38 #include "libdrm_macros.h"
     39 #include "intel_bufmgr.h"
     40 #include "intel_bufmgr_priv.h"
     41 #include "xf86drm.h"
     42 
     43 /** @file intel_bufmgr.c
     44  *
     45  * Convenience functions for buffer management methods.
     46  */
     47 
     48 drm_intel_bo *
     49 drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
     50 		   unsigned long size, unsigned int alignment)
     51 {
     52 	return bufmgr->bo_alloc(bufmgr, name, size, alignment);
     53 }
     54 
     55 drm_intel_bo *
     56 drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name,
     57 			      unsigned long size, unsigned int alignment)
     58 {
     59 	return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
     60 }
     61 
     62 drm_intel_bo *
     63 drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
     64 			   const char *name, void *addr,
     65 			   uint32_t tiling_mode,
     66 			   uint32_t stride,
     67 			   unsigned long size,
     68 			   unsigned long flags)
     69 {
     70 	if (bufmgr->bo_alloc_userptr)
     71 		return bufmgr->bo_alloc_userptr(bufmgr, name, addr, tiling_mode,
     72 						stride, size, flags);
     73 	return NULL;
     74 }
     75 
     76 drm_intel_bo *
     77 drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
     78                         int x, int y, int cpp, uint32_t *tiling_mode,
     79                         unsigned long *pitch, unsigned long flags)
     80 {
     81 	return bufmgr->bo_alloc_tiled(bufmgr, name, x, y, cpp,
     82 				      tiling_mode, pitch, flags);
     83 }
     84 
     85 void
     86 drm_intel_bo_reference(drm_intel_bo *bo)
     87 {
     88 	bo->bufmgr->bo_reference(bo);
     89 }
     90 
     91 void
     92 drm_intel_bo_unreference(drm_intel_bo *bo)
     93 {
     94 	if (bo == NULL)
     95 		return;
     96 
     97 	bo->bufmgr->bo_unreference(bo);
     98 }
     99 
    100 int
    101 drm_intel_bo_map(drm_intel_bo *buf, int write_enable)
    102 {
    103 	return buf->bufmgr->bo_map(buf, write_enable);
    104 }
    105 
    106 int
    107 drm_intel_bo_unmap(drm_intel_bo *buf)
    108 {
    109 	return buf->bufmgr->bo_unmap(buf);
    110 }
    111 
    112 int
    113 drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset,
    114 		     unsigned long size, const void *data)
    115 {
    116 	return bo->bufmgr->bo_subdata(bo, offset, size, data);
    117 }
    118 
    119 int
    120 drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
    121 			 unsigned long size, void *data)
    122 {
    123 	int ret;
    124 	if (bo->bufmgr->bo_get_subdata)
    125 		return bo->bufmgr->bo_get_subdata(bo, offset, size, data);
    126 
    127 	if (size == 0 || data == NULL)
    128 		return 0;
    129 
    130 	ret = drm_intel_bo_map(bo, 0);
    131 	if (ret)
    132 		return ret;
    133 	memcpy(data, (unsigned char *)bo->virtual + offset, size);
    134 	drm_intel_bo_unmap(bo);
    135 	return 0;
    136 }
    137 
    138 void
    139 drm_intel_bo_wait_rendering(drm_intel_bo *bo)
    140 {
    141 	bo->bufmgr->bo_wait_rendering(bo);
    142 }
    143 
    144 void
    145 drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr)
    146 {
    147 	bufmgr->destroy(bufmgr);
    148 }
    149 
    150 int
    151 drm_intel_bo_exec(drm_intel_bo *bo, int used,
    152 		  drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
    153 {
    154 	return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
    155 }
    156 
    157 int
    158 drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
    159 		drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
    160 		unsigned int rings)
    161 {
    162 	if (bo->bufmgr->bo_mrb_exec)
    163 		return bo->bufmgr->bo_mrb_exec(bo, used,
    164 					cliprects, num_cliprects, DR4,
    165 					rings);
    166 
    167 	switch (rings) {
    168 	case I915_EXEC_DEFAULT:
    169 	case I915_EXEC_RENDER:
    170 		return bo->bufmgr->bo_exec(bo, used,
    171 					   cliprects, num_cliprects, DR4);
    172 	default:
    173 		return -ENODEV;
    174 	}
    175 }
    176 
    177 void
    178 drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug)
    179 {
    180 	bufmgr->debug = enable_debug;
    181 }
    182 
    183 int
    184 drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
    185 {
    186 	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
    187 }
    188 
    189 int
    190 drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
    191 {
    192 	if (bo->bufmgr->bo_flink)
    193 		return bo->bufmgr->bo_flink(bo, name);
    194 
    195 	return -ENODEV;
    196 }
    197 
    198 int
    199 drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
    200 			drm_intel_bo *target_bo, uint32_t target_offset,
    201 			uint32_t read_domains, uint32_t write_domain)
    202 {
    203 	return bo->bufmgr->bo_emit_reloc(bo, offset,
    204 					 target_bo, target_offset,
    205 					 read_domains, write_domain);
    206 }
    207 
    208 /* For fence registers, not GL fences */
    209 int
    210 drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
    211 			      drm_intel_bo *target_bo, uint32_t target_offset,
    212 			      uint32_t read_domains, uint32_t write_domain)
    213 {
    214 	return bo->bufmgr->bo_emit_reloc_fence(bo, offset,
    215 					       target_bo, target_offset,
    216 					       read_domains, write_domain);
    217 }
    218 
    219 
    220 int
    221 drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
    222 {
    223 	if (bo->bufmgr->bo_pin)
    224 		return bo->bufmgr->bo_pin(bo, alignment);
    225 
    226 	return -ENODEV;
    227 }
    228 
    229 int
    230 drm_intel_bo_unpin(drm_intel_bo *bo)
    231 {
    232 	if (bo->bufmgr->bo_unpin)
    233 		return bo->bufmgr->bo_unpin(bo);
    234 
    235 	return -ENODEV;
    236 }
    237 
    238 int
    239 drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
    240 			uint32_t stride)
    241 {
    242 	if (bo->bufmgr->bo_set_tiling)
    243 		return bo->bufmgr->bo_set_tiling(bo, tiling_mode, stride);
    244 
    245 	*tiling_mode = I915_TILING_NONE;
    246 	return 0;
    247 }
    248 
    249 int
    250 drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
    251 			uint32_t * swizzle_mode)
    252 {
    253 	if (bo->bufmgr->bo_get_tiling)
    254 		return bo->bufmgr->bo_get_tiling(bo, tiling_mode, swizzle_mode);
    255 
    256 	*tiling_mode = I915_TILING_NONE;
    257 	*swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
    258 	return 0;
    259 }
    260 
    261 int
    262 drm_intel_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
    263 {
    264 	if (bo->bufmgr->bo_set_softpin_offset)
    265 		return bo->bufmgr->bo_set_softpin_offset(bo, offset);
    266 
    267 	return -ENODEV;
    268 }
    269 
    270 int
    271 drm_intel_bo_disable_reuse(drm_intel_bo *bo)
    272 {
    273 	if (bo->bufmgr->bo_disable_reuse)
    274 		return bo->bufmgr->bo_disable_reuse(bo);
    275 	return 0;
    276 }
    277 
    278 int
    279 drm_intel_bo_is_reusable(drm_intel_bo *bo)
    280 {
    281 	if (bo->bufmgr->bo_is_reusable)
    282 		return bo->bufmgr->bo_is_reusable(bo);
    283 	return 0;
    284 }
    285 
    286 int
    287 drm_intel_bo_busy(drm_intel_bo *bo)
    288 {
    289 	if (bo->bufmgr->bo_busy)
    290 		return bo->bufmgr->bo_busy(bo);
    291 	return 0;
    292 }
    293 
    294 int
    295 drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
    296 {
    297 	if (bo->bufmgr->bo_madvise)
    298 		return bo->bufmgr->bo_madvise(bo, madv);
    299 	return -1;
    300 }
    301 
    302 int
    303 drm_intel_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
    304 {
    305 	if (bo->bufmgr->bo_use_48b_address_range) {
    306 		bo->bufmgr->bo_use_48b_address_range(bo, enable);
    307 		return 0;
    308 	}
    309 
    310 	return -ENODEV;
    311 }
    312 
    313 int
    314 drm_intel_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
    315 {
    316 	return bo->bufmgr->bo_references(bo, target_bo);
    317 }
    318 
    319 int
    320 drm_intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
    321 {
    322 	if (bufmgr->get_pipe_from_crtc_id)
    323 		return bufmgr->get_pipe_from_crtc_id(bufmgr, crtc_id);
    324 	return -1;
    325 }
    326 
    327 #ifndef __ANDROID__
    328 static size_t
    329 drm_intel_probe_agp_aperture_size(int fd)
    330 {
    331 	struct pci_device *pci_dev;
    332 	size_t size = 0;
    333 	int ret;
    334 
    335 	ret = pci_system_init();
    336 	if (ret)
    337 		goto err;
    338 
    339 	/* XXX handle multiple adaptors? */
    340 	pci_dev = pci_device_find_by_slot(0, 0, 2, 0);
    341 	if (pci_dev == NULL)
    342 		goto err;
    343 
    344 	ret = pci_device_probe(pci_dev);
    345 	if (ret)
    346 		goto err;
    347 
    348 	size = pci_dev->regions[2].size;
    349 err:
    350 	pci_system_cleanup ();
    351 	return size;
    352 }
    353 #else
    354 static size_t
    355 drm_intel_probe_agp_aperture_size(int fd)
    356 {
    357 	/* Nothing seems to rely on this value on Android anyway... */
    358 	fprintf(stderr, "%s: Mappable aperture size hardcoded to 64MiB\n", __func__);
    359 	return 64 * 1024 * 1024;
    360 }
    361 #endif
    362 
    363 int
    364 drm_intel_get_aperture_sizes(int fd, size_t *mappable, size_t *total)
    365 {
    366 
    367 	struct drm_i915_gem_get_aperture aperture;
    368 	int ret;
    369 
    370 	ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
    371 	if (ret)
    372 		return ret;
    373 
    374 	*mappable = 0;
    375 	/* XXX add a query for the kernel value? */
    376 	if (*mappable == 0)
    377 		*mappable = drm_intel_probe_agp_aperture_size(fd);
    378 	if (*mappable == 0)
    379 		*mappable = 64 * 1024 * 1024; /* minimum possible value */
    380 	*total = aperture.aper_size;
    381 	return 0;
    382 }
    383