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