Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2012-2013 LunarG, Inc.
5
 *
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:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
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.
23
 *
24
 * Authors:
25
 *    Chia-I Wu 
26
 */
27
 
28
#include 
29
#include 
30
#ifndef ETIME
31
#define ETIME ETIMEDOUT
32
#endif
33
 
34
#include 
35
#include 
36
#include 
37
 
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"
44
 
45
#define BATCH_SZ (8192 * sizeof(uint32_t))
46
 
47
struct intel_winsys {
48
   int fd;
49
   drm_intel_bufmgr *bufmgr;
50
   struct intel_winsys_info info;
51
 
52
   struct drm_intel_decode *decode;
53
};
54
 
55
static bool
56
get_param(struct intel_winsys *winsys, int param, int *value)
57
{
58
   struct drm_i915_getparam gp;
59
   int err;
60
 
61
   *value = 0;
62
 
63
   memset(&gp, 0, sizeof(gp));
64
   gp.param = param;
65
   gp.value = value;
66
 
5063 serge 67
   err = drmIoctl(winsys->fd, DRM_I915_GETPARAM, &gp);
68
 
4358 Serge 69
   if (err) {
70
      *value = 0;
71
      return false;
72
   }
73
 
74
   return true;
75
}
76
 
77
static bool
78
test_address_swizzling(struct intel_winsys *winsys)
79
{
80
   drm_intel_bo *bo;
81
   uint32_t tiling = I915_TILING_X, swizzle;
82
   unsigned long pitch;
83
 
84
   bo = drm_intel_bo_alloc_tiled(winsys->bufmgr,
85
         "address swizzling test", 64, 64, 4, &tiling, &pitch, 0);
86
   if (bo) {
87
      drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
88
      drm_intel_bo_unreference(bo);
89
   }
90
   else {
91
      swizzle = I915_BIT_6_SWIZZLE_NONE;
92
   }
93
 
94
   return (swizzle != I915_BIT_6_SWIZZLE_NONE);
95
}
96
 
97
static bool
98
init_info(struct intel_winsys *winsys)
99
{
100
   struct intel_winsys_info *info = &winsys->info;
101
   int val;
102
 
103
   /* follow the classic driver here */
104
   get_param(winsys, I915_PARAM_HAS_RELAXED_DELTA, &val);
105
   if (!val) {
106
      debug_error("kernel 2.6.39 required");
107
      return false;
108
   }
109
 
110
   info->devid = drm_intel_bufmgr_gem_get_devid(winsys->bufmgr);
111
 
112
   get_param(winsys, I915_PARAM_HAS_LLC, &val);
113
   info->has_llc = val;
114
 
115
   get_param(winsys, I915_PARAM_HAS_GEN7_SOL_RESET, &val);
116
   info->has_gen7_sol_reset = val;
117
 
118
   info->has_address_swizzling = test_address_swizzling(winsys);
119
 
120
   return true;
121
}
122
 
123
struct intel_winsys *
124
intel_winsys_create_for_fd(int fd)
125
{
126
   struct intel_winsys *winsys;
127
 
128
   winsys = CALLOC_STRUCT(intel_winsys);
129
   if (!winsys)
130
      return NULL;
131
 
132
   winsys->fd = fd;
133
 
134
   winsys->bufmgr = drm_intel_bufmgr_gem_init(winsys->fd, BATCH_SZ);
135
   if (!winsys->bufmgr) {
136
      debug_error("failed to create GEM buffer manager");
137
      FREE(winsys);
138
      return NULL;
139
   }
140
 
141
   if (!init_info(winsys)) {
142
      drm_intel_bufmgr_destroy(winsys->bufmgr);
143
      FREE(winsys);
144
      return NULL;
145
   }
146
 
147
   drm_intel_bufmgr_gem_enable_fenced_relocs(winsys->bufmgr);
148
 
149
   return winsys;
150
}
151
 
152
void
153
intel_winsys_destroy(struct intel_winsys *winsys)
154
{
5063 serge 155
//   if (winsys->decode)
156
//      drm_intel_decode_context_free(winsys->decode);
4358 Serge 157
 
158
   drm_intel_bufmgr_destroy(winsys->bufmgr);
159
   FREE(winsys);
160
}
161
 
162
const struct intel_winsys_info *
163
intel_winsys_get_info(const struct intel_winsys *winsys)
164
{
165
   return &winsys->info;
166
}
167
 
168
void
169
intel_winsys_enable_reuse(struct intel_winsys *winsys)
170
{
171
   drm_intel_bufmgr_gem_enable_reuse(winsys->bufmgr);
172
}
173
 
174
struct intel_context *
175
intel_winsys_create_context(struct intel_winsys *winsys)
176
{
177
   return (struct intel_context *)
178
      drm_intel_gem_context_create(winsys->bufmgr);
179
}
180
 
181
void
182
intel_winsys_destroy_context(struct intel_winsys *winsys,
183
                             struct intel_context *ctx)
184
{
185
   drm_intel_gem_context_destroy((drm_intel_context *) ctx);
186
}
187
 
188
int
189
intel_winsys_read_reg(struct intel_winsys *winsys,
190
                      uint32_t reg, uint64_t *val)
191
{
192
   return drm_intel_reg_read(winsys->bufmgr, reg, val);
193
}
194
 
195
struct intel_bo *
196
intel_winsys_alloc_buffer(struct intel_winsys *winsys,
197
                          const char *name,
198
                          unsigned long size,
199
                          unsigned long flags)
200
{
201
   const int alignment = 4096; /* always page-aligned */
202
   drm_intel_bo *bo;
203
 
204
   if (flags == INTEL_ALLOC_FOR_RENDER) {
205
      bo = drm_intel_bo_alloc_for_render(winsys->bufmgr,
206
            name, size, alignment);
207
   }
208
   else {
209
      assert(!flags);
210
      bo = drm_intel_bo_alloc(winsys->bufmgr, name, size, alignment);
211
   }
212
 
213
   return (struct intel_bo *) bo;
214
}
215
 
216
struct intel_bo *
217
intel_winsys_alloc_texture(struct intel_winsys *winsys,
218
                           const char *name,
219
                           int width, int height, int cpp,
220
                           enum intel_tiling_mode tiling,
221
                           unsigned long flags,
222
                           unsigned long *pitch)
223
{
224
   uint32_t real_tiling = tiling;
225
   drm_intel_bo *bo;
226
 
227
   bo = drm_intel_bo_alloc_tiled(winsys->bufmgr, name,
228
         width, height, cpp, &real_tiling, pitch, flags);
229
   if (!bo)
230
      return NULL;
231
 
232
   if (real_tiling != tiling) {
233
      assert(!"tiling mismatch");
234
      drm_intel_bo_unreference(bo);
235
      return NULL;
236
   }
237
 
238
   return (struct intel_bo *) bo;
239
}
240
 
241
struct intel_bo *
242
intel_winsys_import_handle(struct intel_winsys *winsys,
243
                           const char *name,
244
                           const struct winsys_handle *handle,
245
                           int width, int height, int cpp,
246
                           enum intel_tiling_mode *tiling,
247
                           unsigned long *pitch)
248
{
249
   uint32_t real_tiling, swizzle;
250
   drm_intel_bo *bo;
251
   int err;
252
 
253
   switch (handle->type) {
254
   case DRM_API_HANDLE_TYPE_SHARED:
255
      {
256
         const uint32_t gem_name = handle->handle;
257
         bo = drm_intel_bo_gem_create_from_name(winsys->bufmgr,
258
               name, gem_name);
259
      }
260
      break;
261
#if 0
262
   case DRM_API_HANDLE_TYPE_FD:
263
      {
264
         const int fd = (int) handle->handle;
265
         bo = drm_intel_bo_gem_create_from_prime(winsys->bufmgr,
266
               fd, height * handle->stride);
267
      }
268
      break;
269
#endif
270
   default:
271
      bo = NULL;
272
      break;
273
   }
274
 
275
   if (!bo)
276
      return NULL;
277
 
278
   err = drm_intel_bo_get_tiling(bo, &real_tiling, &swizzle);
279
   if (err) {
280
      drm_intel_bo_unreference(bo);
281
      return NULL;
282
   }
283
 
284
   *tiling = real_tiling;
285
   *pitch = handle->stride;
286
 
287
   return (struct intel_bo *) bo;
288
}
289
 
290
int
291
intel_winsys_export_handle(struct intel_winsys *winsys,
292
                           struct intel_bo *bo,
293
                           enum intel_tiling_mode tiling,
294
                           unsigned long pitch,
295
                           struct winsys_handle *handle)
296
{
297
   int err = 0;
298
 
299
   switch (handle->type) {
300
   case DRM_API_HANDLE_TYPE_SHARED:
301
      {
302
         uint32_t name;
303
 
304
         err = drm_intel_bo_flink((drm_intel_bo *) bo, &name);
305
         if (!err)
306
            handle->handle = name;
307
      }
308
      break;
309
   case DRM_API_HANDLE_TYPE_KMS:
310
      handle->handle = ((drm_intel_bo *) bo)->handle;
311
      break;
312
#if 0
313
   case DRM_API_HANDLE_TYPE_FD:
314
      {
315
         int fd;
316
 
317
         err = drm_intel_bo_gem_export_to_prime((drm_intel_bo *) bo, &fd);
318
         if (!err)
319
            handle->handle = fd;
320
      }
321
      break;
322
#endif
323
   default:
324
      err = -EINVAL;
325
      break;
326
   }
327
 
328
   if (err)
329
      return err;
330
 
331
   handle->stride = pitch;
332
 
333
   return 0;
334
}
335
 
336
int
337
intel_winsys_check_aperture_space(struct intel_winsys *winsys,
338
                                  struct intel_bo **bo_array,
339
                                  int count)
340
{
341
   return drm_intel_bufmgr_check_aperture_space((drm_intel_bo **) bo_array,
342
                                                count);
343
}
344
 
5063 serge 345
#if 0
4358 Serge 346
void
347
intel_winsys_decode_commands(struct intel_winsys *winsys,
348
                             struct intel_bo *bo, int used)
349
{
350
   int err;
351
 
352
   if (!winsys->decode) {
353
      winsys->decode = drm_intel_decode_context_alloc(winsys->info.devid);
354
      if (!winsys->decode)
355
         return;
356
 
357
      /* debug_printf()/debug_error() uses stderr by default */
358
      drm_intel_decode_set_output_file(winsys->decode, stderr);
359
   }
360
 
361
   err = intel_bo_map(bo, false);
362
   if (err) {
363
      debug_printf("failed to map buffer for decoding\n");
364
      return;
365
   }
366
 
367
   /* in dwords */
368
   used /= 4;
369
 
370
   drm_intel_decode_set_batch_pointer(winsys->decode,
371
         intel_bo_get_virtual(bo), intel_bo_get_offset(bo), used);
372
 
373
   drm_intel_decode(winsys->decode);
374
 
375
   intel_bo_unmap(bo);
376
}
5063 serge 377
#endif
4358 Serge 378
 
379
void
380
intel_bo_reference(struct intel_bo *bo)
381
{
382
   drm_intel_bo_reference((drm_intel_bo *) bo);
383
}
384
 
385
void
386
intel_bo_unreference(struct intel_bo *bo)
387
{
388
   drm_intel_bo_unreference((drm_intel_bo *) bo);
389
}
390
 
391
unsigned long
392
intel_bo_get_size(const struct intel_bo *bo)
393
{
394
   return ((drm_intel_bo *) bo)->size;
395
}
396
 
397
unsigned long
398
intel_bo_get_offset(const struct intel_bo *bo)
399
{
400
   return ((drm_intel_bo *) bo)->offset;
401
}
402
 
403
void *
404
intel_bo_get_virtual(const struct intel_bo *bo)
405
{
406
   return ((drm_intel_bo *) bo)->virtual;
407
}
408
 
409
int
410
intel_bo_map(struct intel_bo *bo, bool write_enable)
411
{
412
   return drm_intel_bo_map((drm_intel_bo *) bo, write_enable);
413
}
414
 
415
int
416
intel_bo_map_gtt(struct intel_bo *bo)
417
{
418
   return drm_intel_gem_bo_map_gtt((drm_intel_bo *) bo);
419
}
420
 
421
int
422
intel_bo_map_unsynchronized(struct intel_bo *bo)
423
{
424
   return drm_intel_gem_bo_map_unsynchronized((drm_intel_bo *) bo);
425
}
426
 
427
void
428
intel_bo_unmap(struct intel_bo *bo)
429
{
430
   int err;
431
 
432
   err = drm_intel_bo_unmap((drm_intel_bo *) bo);
433
   assert(!err);
434
}
435
 
436
int
437
intel_bo_pwrite(struct intel_bo *bo, unsigned long offset,
438
                unsigned long size, const void *data)
439
{
440
   return drm_intel_bo_subdata((drm_intel_bo *) bo, offset, size, data);
441
}
442
 
443
int
444
intel_bo_pread(struct intel_bo *bo, unsigned long offset,
445
               unsigned long size, void *data)
446
{
447
   return drm_intel_bo_get_subdata((drm_intel_bo *) bo, offset, size, data);
448
}
449
 
450
int
451
intel_bo_emit_reloc(struct intel_bo *bo, uint32_t offset,
452
                    struct intel_bo *target_bo, uint32_t target_offset,
453
                    uint32_t read_domains, uint32_t write_domain)
454
{
455
   return drm_intel_bo_emit_reloc((drm_intel_bo *) bo, offset,
456
         (drm_intel_bo *) target_bo, target_offset,
457
         read_domains, write_domain);
458
}
459
 
460
int
461
intel_bo_get_reloc_count(struct intel_bo *bo)
462
{
463
   return drm_intel_gem_bo_get_reloc_count((drm_intel_bo *) bo);
464
}
465
 
466
void
467
intel_bo_clear_relocs(struct intel_bo *bo, int start)
468
{
469
   return drm_intel_gem_bo_clear_relocs((drm_intel_bo *) bo, start);
470
}
471
 
472
bool
473
intel_bo_references(struct intel_bo *bo, struct intel_bo *target_bo)
474
{
475
   return drm_intel_bo_references((drm_intel_bo *) bo,
476
         (drm_intel_bo *) target_bo);
477
}
478
 
479
int
480
intel_bo_exec(struct intel_bo *bo, int used,
481
              struct intel_context *ctx, unsigned long flags)
482
{
483
   if (ctx) {
484
      return drm_intel_gem_bo_context_exec((drm_intel_bo *) bo,
485
            (drm_intel_context *) ctx, used, flags);
486
   }
487
   else {
488
      return drm_intel_bo_mrb_exec((drm_intel_bo *) bo,
489
            used, NULL, 0, 0, flags);
490
   }
491
}
492
 
493
int
494
intel_bo_wait(struct intel_bo *bo, int64_t timeout)
495
{
496
   int err;
497
 
498
   err = drm_intel_gem_bo_wait((drm_intel_bo *) bo, timeout);
499
   /* consider the bo idle on errors */
500
   if (err && err != -ETIME)
501
      err = 0;
502
 
503
   return err;
504
}