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 #ifdef HAVE_CONFIG_H
     29 #include "config.h"
     30 #endif
     31 
     32 #include <string.h>
     33 #include <stdlib.h>
     34 #include <stdint.h>
     35 #include <assert.h>
     36 #include <errno.h>
     37 #include <drm.h>
     38 #include <i915_drm.h>
     39 #ifndef __ANDROID__
     40 #include <pciaccess.h>
     41 #endif
     42 #include "libdrm_macros.h"
     43 #include "intel_bufmgr.h"
     44 #include "intel_bufmgr_priv.h"
     45 #include "xf86drm.h"
     46 
     47 /** @file intel_bufmgr.c
     48  *
     49  * Convenience functions for buffer management methods.
     50  */
     51 
     52 drm_intel_bo *
     53 drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
     54 		   unsigned long size, unsigned int alignment)
     55 {
     56 	return bufmgr->bo_alloc(bufmgr, name, size, alignment);
     57 }
     58 
     59 drm_intel_bo *
     60 drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name,
     61 			      unsigned long size, unsigned int alignment)
     62 {
     63 	return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
     64 }
     65 
     66 drm_intel_bo *
     67 drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
     68 			   const char *name, void *addr,
     69 			   uint32_t tiling_mode,
     70 			   uint32_t stride,
     71 			   unsigned long size,
     72 			   unsigned long flags)
     73 {
     74 	if (bufmgr->bo_alloc_userptr)
     75 		return bufmgr->bo_alloc_userptr(bufmgr, name, addr, tiling_mode,
     76 						stride, size, flags);
     77 	return NULL;
     78 }
     79 
     80 drm_intel_bo *
     81 drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
     82                         int x, int y, int cpp, uint32_t *tiling_mode,
     83                         unsigned long *pitch, unsigned long flags)
     84 {
     85 	return bufmgr->bo_alloc_tiled(bufmgr, name, x, y, cpp,
     86 				      tiling_mode, pitch, flags);
     87 }
     88 
     89 void
     90 drm_intel_bo_reference(drm_intel_bo *bo)
     91 {
     92 	bo->bufmgr->bo_reference(bo);
     93 }
     94 
     95 void
     96 drm_intel_bo_unreference(drm_intel_bo *bo)
     97 {
     98 	if (bo == NULL)
     99 		return;
    100 
    101 	bo->bufmgr->bo_unreference(bo);
    102 }
    103 
    104 int
    105 drm_intel_bo_map(drm_intel_bo *buf, int write_enable)
    106 {
    107 	return buf->bufmgr->bo_map(buf, write_enable);
    108 }
    109 
    110 int
    111 drm_intel_bo_unmap(drm_intel_bo *buf)
    112 {
    113 	return buf->bufmgr->bo_unmap(buf);
    114 }
    115 
    116 int
    117 drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset,
    118 		     unsigned long size, const void *data)
    119 {
    120 	return bo->bufmgr->bo_subdata(bo, offset, size, data);
    121 }
    122 
    123 int
    124 drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
    125 			 unsigned long size, void *data)
    126 {
    127 	int ret;
    128 	if (bo->bufmgr->bo_get_subdata)
    129 		return bo->bufmgr->bo_get_subdata(bo, offset, size, data);
    130 
    131 	if (size == 0 || data == NULL)
    132 		return 0;
    133 
    134 	ret = drm_intel_bo_map(bo, 0);
    135 	if (ret)
    136 		return ret;
    137 	memcpy(data, (unsigned char *)bo->virtual + offset, size);
    138 	drm_intel_bo_unmap(bo);
    139 	return 0;
    140 }
    141 
    142 void
    143 drm_intel_bo_wait_rendering(drm_intel_bo *bo)
    144 {
    145 	bo->bufmgr->bo_wait_rendering(bo);
    146 }
    147 
    148 void
    149 drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr)
    150 {
    151 	bufmgr->destroy(bufmgr);
    152 }
    153 
    154 int
    155 drm_intel_bo_exec(drm_intel_bo *bo, int used,
    156 		  drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
    157 {
    158 	return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
    159 }
    160 
    161 int
    162 drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
    163 		drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
    164 		unsigned int rings)
    165 {
    166 	if (bo->bufmgr->bo_mrb_exec)
    167 		return bo->bufmgr->bo_mrb_exec(bo, used,
    168 					cliprects, num_cliprects, DR4,
    169 					rings);
    170 
    171 	switch (rings) {
    172 	case I915_EXEC_DEFAULT:
    173 	case I915_EXEC_RENDER:
    174 		return bo->bufmgr->bo_exec(bo, used,
    175 					   cliprects, num_cliprects, DR4);
    176 	default:
    177 		return -ENODEV;
    178 	}
    179 }
    180 
    181 void
    182 drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug)
    183 {
    184 	bufmgr->debug = enable_debug;
    185 }
    186 
    187 int
    188 drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
    189 {
    190 	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
    191 }
    192 
    193 int
    194 drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
    195 {
    196 	if (bo->bufmgr->bo_flink)
    197 		return bo->bufmgr->bo_flink(bo, name);
    198 
    199 	return -ENODEV;
    200 }
    201 
    202 int
    203 drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
    204 			drm_intel_bo *target_bo, uint32_t target_offset,
    205 			uint32_t read_domains, uint32_t write_domain)
    206 {
    207 	return bo->bufmgr->bo_emit_reloc(bo, offset,
    208 					 target_bo, target_offset,
    209 					 read_domains, write_domain);
    210 }
    211 
    212 /* For fence registers, not GL fences */
    213 int
    214 drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
    215 			      drm_intel_bo *target_bo, uint32_t target_offset,
    216 			      uint32_t read_domains, uint32_t write_domain)
    217 {
    218 	return bo->bufmgr->bo_emit_reloc_fence(bo, offset,
    219 					       target_bo, target_offset,
    220 					       read_domains, write_domain);
    221 }
    222 
    223 
    224 int
    225 drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
    226 {
    227 	if (bo->bufmgr->bo_pin)
    228 		return bo->bufmgr->bo_pin(bo, alignment);
    229 
    230 	return -ENODEV;
    231 }
    232 
    233 int
    234 drm_intel_bo_unpin(drm_intel_bo *bo)
    235 {
    236 	if (bo->bufmgr->bo_unpin)
    237 		return bo->bufmgr->bo_unpin(bo);
    238 
    239 	return -ENODEV;
    240 }
    241 
    242 int
    243 drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
    244 			uint32_t stride)
    245 {
    246 	if (bo->bufmgr->bo_set_tiling)
    247 		return bo->bufmgr->bo_set_tiling(bo, tiling_mode, stride);
    248 
    249 	*tiling_mode = I915_TILING_NONE;
    250 	return 0;
    251 }
    252 
    253 int
    254 drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
    255 			uint32_t * swizzle_mode)
    256 {
    257 	if (bo->bufmgr->bo_get_tiling)
    258 		return bo->bufmgr->bo_get_tiling(bo, tiling_mode, swizzle_mode);
    259 
    260 	*tiling_mode = I915_TILING_NONE;
    261 	*swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
    262 	return 0;
    263 }
    264 
    265 int
    266 drm_intel_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
    267 {
    268 	if (bo->bufmgr->bo_set_softpin_offset)
    269 		return bo->bufmgr->bo_set_softpin_offset(bo, offset);
    270 
    271 	return -ENODEV;
    272 }
    273 
    274 int
    275 drm_intel_bo_disable_reuse(drm_intel_bo *bo)
    276 {
    277 	if (bo->bufmgr->bo_disable_reuse)
    278 		return bo->bufmgr->bo_disable_reuse(bo);
    279 	return 0;
    280 }
    281 
    282 int
    283 drm_intel_bo_is_reusable(drm_intel_bo *bo)
    284 {
    285 	if (bo->bufmgr->bo_is_reusable)
    286 		return bo->bufmgr->bo_is_reusable(bo);
    287 	return 0;
    288 }
    289 
    290 int
    291 drm_intel_bo_busy(drm_intel_bo *bo)
    292 {
    293 	if (bo->bufmgr->bo_busy)
    294 		return bo->bufmgr->bo_busy(bo);
    295 	return 0;
    296 }
    297 
    298 int
    299 drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
    300 {
    301 	if (bo->bufmgr->bo_madvise)
    302 		return bo->bufmgr->bo_madvise(bo, madv);
    303 	return -1;
    304 }
    305 
    306 int
    307 drm_intel_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
    308 {
    309 	if (bo->bufmgr->bo_use_48b_address_range) {
    310 		bo->bufmgr->bo_use_48b_address_range(bo, enable);
    311 		return 0;
    312 	}
    313 
    314 	return -ENODEV;
    315 }
    316 
    317 int
    318 drm_intel_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
    319 {
    320 	return bo->bufmgr->bo_references(bo, target_bo);
    321 }
    322 
    323 int
    324 drm_intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
    325 {
    326 	if (bufmgr->get_pipe_from_crtc_id)
    327 		return bufmgr->get_pipe_from_crtc_id(bufmgr, crtc_id);
    328 	return -1;
    329 }
    330 
    331 #ifndef __ANDROID__
    332 static size_t
    333 drm_intel_probe_agp_aperture_size(int fd)
    334 {
    335 	struct pci_device *pci_dev;
    336 	size_t size = 0;
    337 	int ret;
    338 
    339 	ret = pci_system_init();
    340 	if (ret)
    341 		goto err;
    342 
    343 	/* XXX handle multiple adaptors? */
    344 	pci_dev = pci_device_find_by_slot(0, 0, 2, 0);
    345 	if (pci_dev == NULL)
    346 		goto err;
    347 
    348 	ret = pci_device_probe(pci_dev);
    349 	if (ret)
    350 		goto err;
    351 
    352 	size = pci_dev->regions[2].size;
    353 err:
    354 	pci_system_cleanup ();
    355 	return size;
    356 }
    357 #else
    358 static size_t
    359 drm_intel_probe_agp_aperture_size(int fd)
    360 {
    361 	/* Nothing seems to rely on this value on Android anyway... */
    362 	fprintf(stderr, "%s: Mappable aperture size hardcoded to 64MiB\n");
    363 	return 64 * 1024 * 1024;
    364 }
    365 #endif
    366 
    367 int
    368 drm_intel_get_aperture_sizes(int fd, size_t *mappable, size_t *total)
    369 {
    370 
    371 	struct drm_i915_gem_get_aperture aperture;
    372 	int ret;
    373 
    374 	ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
    375 	if (ret)
    376 		return ret;
    377 
    378 	*mappable = 0;
    379 	/* XXX add a query for the kernel value? */
    380 	if (*mappable == 0)
    381 		*mappable = drm_intel_probe_agp_aperture_size(fd);
    382 	if (*mappable == 0)
    383 		*mappable = 64 * 1024 * 1024; /* minimum possible value */
    384 	*total = aperture.aper_size;
    385 	return 0;
    386 }
    387