2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
31 #define ETIME ETIMEDOUT
36 #include <intel_bufmgr.h>
38 #include "state_tracker/drm_driver.h"
39 #include "pipe/p_state.h"
40 #include "util/u_inlines.h"
41 #include "util/u_memory.h"
42 #include "util/u_debug.h"
43 #include "../intel_winsys.h"
45 #define BATCH_SZ (8192 * sizeof(uint32_t))
49 drm_intel_bufmgr
*bufmgr
;
50 struct intel_winsys_info info
;
52 struct drm_intel_decode
*decode
;
56 get_param(struct intel_winsys
*winsys
, int param
, int *value
)
58 struct drm_i915_getparam gp
;
63 memset(&gp
, 0, sizeof(gp
));
67 err
= drmCommandWriteRead(winsys
->fd
, DRM_I915_GETPARAM
, &gp
, sizeof(gp
));
77 test_address_swizzling(struct intel_winsys
*winsys
)
80 uint32_t tiling
= I915_TILING_X
, swizzle
;
83 bo
= drm_intel_bo_alloc_tiled(winsys
->bufmgr
,
84 "address swizzling test", 64, 64, 4, &tiling
, &pitch
, 0);
86 drm_intel_bo_get_tiling(bo
, &tiling
, &swizzle
);
87 drm_intel_bo_unreference(bo
);
90 swizzle
= I915_BIT_6_SWIZZLE_NONE
;
93 return (swizzle
!= I915_BIT_6_SWIZZLE_NONE
);
97 init_info(struct intel_winsys
*winsys
)
99 struct intel_winsys_info
*info
= &winsys
->info
;
102 /* follow the classic driver here */
103 get_param(winsys
, I915_PARAM_HAS_RELAXED_DELTA
, &val
);
105 debug_error("kernel 2.6.39 required");
109 info
->devid
= drm_intel_bufmgr_gem_get_devid(winsys
->bufmgr
);
111 get_param(winsys
, I915_PARAM_HAS_LLC
, &val
);
114 get_param(winsys
, I915_PARAM_HAS_GEN7_SOL_RESET
, &val
);
115 info
->has_gen7_sol_reset
= val
;
117 info
->has_address_swizzling
= test_address_swizzling(winsys
);
122 struct intel_winsys
*
123 intel_winsys_create_for_fd(int fd
)
125 struct intel_winsys
*winsys
;
127 winsys
= CALLOC_STRUCT(intel_winsys
);
133 winsys
->bufmgr
= drm_intel_bufmgr_gem_init(winsys
->fd
, BATCH_SZ
);
134 if (!winsys
->bufmgr
) {
135 debug_error("failed to create GEM buffer manager");
140 if (!init_info(winsys
)) {
141 drm_intel_bufmgr_destroy(winsys
->bufmgr
);
146 drm_intel_bufmgr_gem_enable_fenced_relocs(winsys
->bufmgr
);
152 intel_winsys_destroy(struct intel_winsys
*winsys
)
155 drm_intel_decode_context_free(winsys
->decode
);
157 drm_intel_bufmgr_destroy(winsys
->bufmgr
);
161 const struct intel_winsys_info
*
162 intel_winsys_get_info(const struct intel_winsys
*winsys
)
164 return &winsys
->info
;
168 intel_winsys_enable_reuse(struct intel_winsys
*winsys
)
170 drm_intel_bufmgr_gem_enable_reuse(winsys
->bufmgr
);
173 struct intel_context
*
174 intel_winsys_create_context(struct intel_winsys
*winsys
)
176 return (struct intel_context
*)
177 drm_intel_gem_context_create(winsys
->bufmgr
);
181 intel_winsys_destroy_context(struct intel_winsys
*winsys
,
182 struct intel_context
*ctx
)
184 drm_intel_gem_context_destroy((drm_intel_context
*) ctx
);
188 intel_winsys_read_reg(struct intel_winsys
*winsys
,
189 uint32_t reg
, uint64_t *val
)
191 return drm_intel_reg_read(winsys
->bufmgr
, reg
, val
);
195 intel_winsys_alloc_buffer(struct intel_winsys
*winsys
,
200 const int alignment
= 4096; /* always page-aligned */
203 if (flags
== INTEL_ALLOC_FOR_RENDER
) {
204 bo
= drm_intel_bo_alloc_for_render(winsys
->bufmgr
,
205 name
, size
, alignment
);
209 bo
= drm_intel_bo_alloc(winsys
->bufmgr
, name
, size
, alignment
);
212 return (struct intel_bo
*) bo
;
216 intel_winsys_alloc_texture(struct intel_winsys
*winsys
,
218 int width
, int height
, int cpp
,
219 enum intel_tiling_mode tiling
,
221 unsigned long *pitch
)
223 uint32_t real_tiling
= tiling
;
226 bo
= drm_intel_bo_alloc_tiled(winsys
->bufmgr
, name
,
227 width
, height
, cpp
, &real_tiling
, pitch
, flags
);
231 if (real_tiling
!= tiling
) {
232 assert(!"tiling mismatch");
233 drm_intel_bo_unreference(bo
);
237 return (struct intel_bo
*) bo
;
241 intel_winsys_import_handle(struct intel_winsys
*winsys
,
243 const struct winsys_handle
*handle
,
244 int width
, int height
, int cpp
,
245 enum intel_tiling_mode
*tiling
,
246 unsigned long *pitch
)
248 uint32_t real_tiling
, swizzle
;
252 switch (handle
->type
) {
253 case DRM_API_HANDLE_TYPE_SHARED
:
255 const uint32_t gem_name
= handle
->handle
;
256 bo
= drm_intel_bo_gem_create_from_name(winsys
->bufmgr
,
260 case DRM_API_HANDLE_TYPE_FD
:
262 const int fd
= (int) handle
->handle
;
263 bo
= drm_intel_bo_gem_create_from_prime(winsys
->bufmgr
,
264 fd
, height
* handle
->stride
);
275 err
= drm_intel_bo_get_tiling(bo
, &real_tiling
, &swizzle
);
277 drm_intel_bo_unreference(bo
);
281 *tiling
= real_tiling
;
282 *pitch
= handle
->stride
;
284 return (struct intel_bo
*) bo
;
288 intel_winsys_export_handle(struct intel_winsys
*winsys
,
290 enum intel_tiling_mode tiling
,
292 struct winsys_handle
*handle
)
296 switch (handle
->type
) {
297 case DRM_API_HANDLE_TYPE_SHARED
:
301 err
= drm_intel_bo_flink((drm_intel_bo
*) bo
, &name
);
303 handle
->handle
= name
;
306 case DRM_API_HANDLE_TYPE_KMS
:
307 handle
->handle
= ((drm_intel_bo
*) bo
)->handle
;
310 case DRM_API_HANDLE_TYPE_FD
:
314 err
= drm_intel_bo_gem_export_to_prime((drm_intel_bo
*) bo
, &fd
);
328 handle
->stride
= pitch
;
334 intel_winsys_check_aperture_space(struct intel_winsys
*winsys
,
335 struct intel_bo
**bo_array
,
338 return drm_intel_bufmgr_check_aperture_space((drm_intel_bo
**) bo_array
,
343 intel_winsys_decode_commands(struct intel_winsys
*winsys
,
344 struct intel_bo
*bo
, int used
)
348 if (!winsys
->decode
) {
349 winsys
->decode
= drm_intel_decode_context_alloc(winsys
->info
.devid
);
353 /* debug_printf()/debug_error() uses stderr by default */
354 drm_intel_decode_set_output_file(winsys
->decode
, stderr
);
357 err
= intel_bo_map(bo
, false);
359 debug_printf("failed to map buffer for decoding\n");
366 drm_intel_decode_set_batch_pointer(winsys
->decode
,
367 intel_bo_get_virtual(bo
), intel_bo_get_offset(bo
), used
);
369 drm_intel_decode(winsys
->decode
);
375 intel_bo_reference(struct intel_bo
*bo
)
377 drm_intel_bo_reference((drm_intel_bo
*) bo
);
381 intel_bo_unreference(struct intel_bo
*bo
)
383 drm_intel_bo_unreference((drm_intel_bo
*) bo
);
387 intel_bo_get_size(const struct intel_bo
*bo
)
389 return ((drm_intel_bo
*) bo
)->size
;
393 intel_bo_get_offset(const struct intel_bo
*bo
)
395 return ((drm_intel_bo
*) bo
)->offset
;
399 intel_bo_get_virtual(const struct intel_bo
*bo
)
401 return ((drm_intel_bo
*) bo
)->virtual;
405 intel_bo_map(struct intel_bo
*bo
, bool write_enable
)
407 return drm_intel_bo_map((drm_intel_bo
*) bo
, write_enable
);
411 intel_bo_map_gtt(struct intel_bo
*bo
)
413 return drm_intel_gem_bo_map_gtt((drm_intel_bo
*) bo
);
417 intel_bo_map_unsynchronized(struct intel_bo
*bo
)
419 return drm_intel_gem_bo_map_unsynchronized((drm_intel_bo
*) bo
);
423 intel_bo_unmap(struct intel_bo
*bo
)
427 err
= drm_intel_bo_unmap((drm_intel_bo
*) bo
);
432 intel_bo_pwrite(struct intel_bo
*bo
, unsigned long offset
,
433 unsigned long size
, const void *data
)
435 return drm_intel_bo_subdata((drm_intel_bo
*) bo
, offset
, size
, data
);
439 intel_bo_pread(struct intel_bo
*bo
, unsigned long offset
,
440 unsigned long size
, void *data
)
442 return drm_intel_bo_get_subdata((drm_intel_bo
*) bo
, offset
, size
, data
);
446 intel_bo_emit_reloc(struct intel_bo
*bo
, uint32_t offset
,
447 struct intel_bo
*target_bo
, uint32_t target_offset
,
448 uint32_t read_domains
, uint32_t write_domain
)
450 return drm_intel_bo_emit_reloc((drm_intel_bo
*) bo
, offset
,
451 (drm_intel_bo
*) target_bo
, target_offset
,
452 read_domains
, write_domain
);
456 intel_bo_get_reloc_count(struct intel_bo
*bo
)
458 return drm_intel_gem_bo_get_reloc_count((drm_intel_bo
*) bo
);
462 intel_bo_clear_relocs(struct intel_bo
*bo
, int start
)
464 return drm_intel_gem_bo_clear_relocs((drm_intel_bo
*) bo
, start
);
468 intel_bo_references(struct intel_bo
*bo
, struct intel_bo
*target_bo
)
470 return drm_intel_bo_references((drm_intel_bo
*) bo
,
471 (drm_intel_bo
*) target_bo
);
475 intel_bo_exec(struct intel_bo
*bo
, int used
,
476 struct intel_context
*ctx
, unsigned long flags
)
479 return drm_intel_gem_bo_context_exec((drm_intel_bo
*) bo
,
480 (drm_intel_context
*) ctx
, used
, flags
);
483 return drm_intel_bo_mrb_exec((drm_intel_bo
*) bo
,
484 used
, NULL
, 0, 0, flags
);
489 intel_bo_wait(struct intel_bo
*bo
, int64_t timeout
)
493 err
= drm_intel_gem_bo_wait((drm_intel_bo
*) bo
, timeout
);
494 /* consider the bo idle on errors */
495 if (err
&& err
!= -ETIME
)