Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4304 Serge 1
/**************************************************************************
2
 
3
Copyright 2001 VA Linux Systems Inc., Fremont, California.
4
Copyright © 2002 by David Dawes
5
 
6
All Rights Reserved.
7
 
8
Permission is hereby granted, free of charge, to any person obtaining a
9
copy of this software and associated documentation files (the "Software"),
10
to deal in the Software without restriction, including without limitation
11
on the rights to use, copy, modify, merge, publish, distribute, sub
12
license, and/or sell copies of the Software, and to permit persons to whom
13
the Software is furnished to do so, subject to the following conditions:
14
 
15
The above copyright notice and this permission notice (including the next
16
paragraph) shall be included in all copies or substantial portions of the
17
Software.
18
 
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22
THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25
USE OR OTHER DEALINGS IN THE SOFTWARE.
26
 
27
**************************************************************************/
28
 
29
/*
30
 * Authors: Jeff Hartmann 
31
 *          Abraham van der Merwe 
32
 *          David Dawes 
33
 *          Alan Hourihane 
34
 */
35
 
36
#ifdef HAVE_CONFIG_H
37
#include "config.h"
38
#endif
39
 
40
#include 
41
#include 
42
#include "i915_pciids.h"
43
 
44
#include "compiler.h"
45
#include "sna.h"
4375 Serge 46
#include "sna_reg.h"
4304 Serge 47
 
4315 Serge 48
#include 
4377 Serge 49
#include "../pixdriver.h"
50
 
4315 Serge 51
#include 
52
 
4304 Serge 53
#define to_surface(x) (surface_t*)((x)->handle)
54
 
4368 Serge 55
typedef struct {
56
    int l;
57
    int t;
58
    int r;
59
    int b;
60
} rect_t;
61
 
4304 Serge 62
static struct sna_fb sna_fb;
63
static int    tls_mask;
64
 
65
int tls_alloc(void);
66
 
67
static inline void *tls_get(int key)
68
{
69
    void *val;
70
    __asm__ __volatile__(
71
    "movl %%fs:(%1), %0"
72
    :"=r"(val)
73
    :"r"(key));
74
 
75
  return val;
76
};
77
 
78
static inline int
79
tls_set(int key, const void *ptr)
80
{
81
    if(!(key & 3))
82
    {
83
        __asm__ __volatile__(
84
        "movl %0, %%fs:(%1)"
85
        ::"r"(ptr),"r"(key));
86
        return 0;
87
    }
88
    else return -1;
89
}
90
 
91
 
92
 
93
 
94
int kgem_init_fb(struct kgem *kgem, struct sna_fb *fb);
95
int kgem_update_fb(struct kgem *kgem, struct sna_fb *fb);
96
uint32_t kgem_surface_size(struct kgem *kgem,bool relaxed_fencing,
97
				  unsigned flags, uint32_t width, uint32_t height,
98
				  uint32_t bpp, uint32_t tiling, uint32_t *pitch);
99
struct kgem_bo *kgem_bo_from_handle(struct kgem *kgem, int handle,
100
                        int pitch, int height);
101
 
102
void kgem_close_batches(struct kgem *kgem);
103
void sna_bo_destroy(struct kgem *kgem, struct kgem_bo *bo);
104
 
105
 
106
static bool sna_solid_cache_init(struct sna *sna);
107
 
108
struct sna *sna_device;
109
 
110
__LOCK_INIT_RECURSIVE(, __sna_lock);
111
 
112
static void no_render_reset(struct sna *sna)
113
{
114
	(void)sna;
115
}
116
 
117
static void no_render_flush(struct sna *sna)
118
{
119
	(void)sna;
120
}
121
 
122
static void
123
no_render_context_switch(struct kgem *kgem,
124
			 int new_mode)
125
{
126
	if (!kgem->nbatch)
127
		return;
128
 
129
	if (kgem_ring_is_idle(kgem, kgem->ring)) {
130
		DBG(("%s: GPU idle, flushing\n", __FUNCTION__));
131
		_kgem_submit(kgem);
132
	}
133
 
134
	(void)new_mode;
135
}
136
 
137
static void
138
no_render_retire(struct kgem *kgem)
139
{
140
	(void)kgem;
141
}
142
 
143
static void
144
no_render_expire(struct kgem *kgem)
145
{
146
	(void)kgem;
147
}
148
 
149
static void
150
no_render_fini(struct sna *sna)
151
{
152
	(void)sna;
153
}
154
 
155
const char *no_render_init(struct sna *sna)
156
{
157
    struct sna_render *render = &sna->render;
158
 
159
    memset (render,0, sizeof (*render));
160
 
161
    render->prefer_gpu = PREFER_GPU_BLT;
162
 
163
    render->vertices = render->vertex_data;
164
    render->vertex_size = ARRAY_SIZE(render->vertex_data);
165
 
166
    render->reset = no_render_reset;
167
	render->flush = no_render_flush;
168
	render->fini = no_render_fini;
169
 
170
	sna->kgem.context_switch = no_render_context_switch;
171
	sna->kgem.retire = no_render_retire;
172
	sna->kgem.expire = no_render_expire;
173
 
174
	sna->kgem.mode = KGEM_RENDER;
175
	sna->kgem.ring = KGEM_RENDER;
176
 
177
	sna_vertex_init(sna);
178
	return "generic";
179
 }
180
 
181
void sna_vertex_init(struct sna *sna)
182
{
183
//    pthread_mutex_init(&sna->render.lock, NULL);
184
//    pthread_cond_init(&sna->render.wait, NULL);
185
    sna->render.active = 0;
186
}
187
 
188
int sna_accel_init(struct sna *sna)
189
{
190
    const char *backend;
191
 
192
	backend = no_render_init(sna);
193
	if (sna->info->gen >= 0100)
194
		(void)backend;
195
	else if (sna->info->gen >= 070)
196
		backend = gen7_render_init(sna, backend);
197
	else if (sna->info->gen >= 060)
198
		backend = gen6_render_init(sna, backend);
199
	else if (sna->info->gen >= 050)
200
		backend = gen5_render_init(sna, backend);
201
	else if (sna->info->gen >= 040)
202
		backend = gen4_render_init(sna, backend);
203
	else if (sna->info->gen >= 030)
204
		backend = gen3_render_init(sna, backend);
205
 
206
	DBG(("%s(backend=%s, prefer_gpu=%x)\n",
207
	     __FUNCTION__, backend, sna->render.prefer_gpu));
208
 
209
	kgem_reset(&sna->kgem);
210
 
211
    sna_device = sna;
212
 
213
    return kgem_init_fb(&sna->kgem, &sna_fb);
214
}
215
 
216
 
217
#if 0
218
 
219
static bool sna_solid_cache_init(struct sna *sna)
220
{
221
    struct sna_solid_cache *cache = &sna->render.solid_cache;
222
 
223
    DBG(("%s\n", __FUNCTION__));
224
 
225
    cache->cache_bo =
226
        kgem_create_linear(&sna->kgem, sizeof(cache->color));
227
    if (!cache->cache_bo)
228
        return FALSE;
229
 
230
    /*
231
     * Initialise [0] with white since it is very common and filling the
232
     * zeroth slot simplifies some of the checks.
233
     */
234
    cache->color[0] = 0xffffffff;
235
    cache->bo[0] = kgem_create_proxy(cache->cache_bo, 0, sizeof(uint32_t));
236
    cache->bo[0]->pitch = 4;
237
    cache->dirty = 1;
238
    cache->size = 1;
239
    cache->last = 0;
240
 
241
    return TRUE;
242
}
243
 
244
void
245
sna_render_flush_solid(struct sna *sna)
246
{
247
    struct sna_solid_cache *cache = &sna->render.solid_cache;
248
 
249
    DBG(("sna_render_flush_solid(size=%d)\n", cache->size));
250
    assert(cache->dirty);
251
    assert(cache->size);
252
 
253
    kgem_bo_write(&sna->kgem, cache->cache_bo,
254
              cache->color, cache->size*sizeof(uint32_t));
255
    cache->dirty = 0;
256
    cache->last = 0;
257
}
258
 
259
static void
260
sna_render_finish_solid(struct sna *sna, bool force)
261
{
262
    struct sna_solid_cache *cache = &sna->render.solid_cache;
263
    int i;
264
 
265
    DBG(("sna_render_finish_solid(force=%d, domain=%d, busy=%d, dirty=%d)\n",
266
         force, cache->cache_bo->domain, cache->cache_bo->rq != NULL, cache->dirty));
267
 
268
    if (!force && cache->cache_bo->domain != DOMAIN_GPU)
269
        return;
270
 
271
    if (cache->dirty)
272
        sna_render_flush_solid(sna);
273
 
274
    for (i = 0; i < cache->size; i++) {
275
        if (cache->bo[i] == NULL)
276
            continue;
277
 
278
        kgem_bo_destroy(&sna->kgem, cache->bo[i]);
279
        cache->bo[i] = NULL;
280
    }
281
    kgem_bo_destroy(&sna->kgem, cache->cache_bo);
282
 
283
    DBG(("sna_render_finish_solid reset\n"));
284
 
285
    cache->cache_bo = kgem_create_linear(&sna->kgem, sizeof(cache->color));
286
    cache->bo[0] = kgem_create_proxy(cache->cache_bo, 0, sizeof(uint32_t));
287
    cache->bo[0]->pitch = 4;
288
    if (force)
289
        cache->size = 1;
290
}
291
 
292
 
293
struct kgem_bo *
294
sna_render_get_solid(struct sna *sna, uint32_t color)
295
{
296
    struct sna_solid_cache *cache = &sna->render.solid_cache;
297
    int i;
298
 
299
    DBG(("%s: %08x\n", __FUNCTION__, color));
300
 
301
//    if ((color & 0xffffff) == 0) /* alpha only */
302
//        return kgem_bo_reference(sna->render.alpha_cache.bo[color>>24]);
303
 
304
    if (color == 0xffffffff) {
305
        DBG(("%s(white)\n", __FUNCTION__));
306
        return kgem_bo_reference(cache->bo[0]);
307
    }
308
 
309
    if (cache->color[cache->last] == color) {
310
        DBG(("sna_render_get_solid(%d) = %x (last)\n",
311
             cache->last, color));
312
        return kgem_bo_reference(cache->bo[cache->last]);
313
    }
314
 
315
    for (i = 1; i < cache->size; i++) {
316
        if (cache->color[i] == color) {
317
            if (cache->bo[i] == NULL) {
318
                DBG(("sna_render_get_solid(%d) = %x (recreate)\n",
319
                     i, color));
320
                goto create;
321
            } else {
322
                DBG(("sna_render_get_solid(%d) = %x (old)\n",
323
                     i, color));
324
                goto done;
325
            }
326
        }
327
    }
328
 
329
    sna_render_finish_solid(sna, i == ARRAY_SIZE(cache->color));
330
 
331
    i = cache->size++;
332
    cache->color[i] = color;
333
    cache->dirty = 1;
334
    DBG(("sna_render_get_solid(%d) = %x (new)\n", i, color));
335
 
336
create:
337
    cache->bo[i] = kgem_create_proxy(cache->cache_bo,
338
                     i*sizeof(uint32_t), sizeof(uint32_t));
339
    cache->bo[i]->pitch = 4;
340
 
341
done:
342
    cache->last = i;
343
    return kgem_bo_reference(cache->bo[i]);
344
}
345
 
346
#endif
347
 
348
 
349
int sna_blit_copy(bitmap_t *src_bitmap, int dst_x, int dst_y,
350
                  int w, int h, int src_x, int src_y)
351
 
352
{
353
    struct sna_copy_op copy;
354
    struct _Pixmap src, dst;
355
    struct kgem_bo *src_bo;
356
 
357
    char proc_info[1024];
358
    int winx, winy;
359
 
360
    get_proc_info(proc_info);
361
 
362
    winx = *(uint32_t*)(proc_info+34);
363
    winy = *(uint32_t*)(proc_info+38);
364
 
365
    memset(&src, 0, sizeof(src));
366
    memset(&dst, 0, sizeof(dst));
367
 
368
    src.drawable.bitsPerPixel = 32;
369
    src.drawable.width  = src_bitmap->width;
370
    src.drawable.height = src_bitmap->height;
371
 
372
    dst.drawable.bitsPerPixel = 32;
373
    dst.drawable.width  = sna_fb.width;
374
    dst.drawable.height = sna_fb.height;
375
 
376
    memset(©, 0, sizeof(copy));
377
 
378
    src_bo = (struct kgem_bo*)src_bitmap->handle;
379
 
380
    if( sna_device->render.copy(sna_device, GXcopy,
381
                                &src, src_bo,
382
                                &dst, sna_fb.fb_bo, ©) )
383
    {
384
        copy.blt(sna_device, ©, src_x, src_y, w, h, winx+dst_x, winy+dst_y);
385
        copy.done(sna_device, ©);
386
    }
387
 
388
    kgem_submit(&sna_device->kgem);
389
 
390
    return 0;
391
 
392
//    __asm__ __volatile__("int3");
393
 
394
};
395
 
396
typedef struct
397
{
398
    uint32_t        width;
399
    uint32_t        height;
400
    void           *data;
401
    uint32_t        pitch;
402
    struct kgem_bo *bo;
403
    uint32_t        bo_size;
404
    uint32_t        flags;
405
}surface_t;
406
 
407
 
408
 
4372 Serge 409
 
410
#define MI_LOAD_REGISTER_IMM		(0x22<<23)
411
#define MI_WAIT_FOR_EVENT			(0x03<<23)
412
 
4375 Serge 413
static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
414
                        rect_t *crtc,
415
                        int pipe, int y1, int y2,
416
                        bool full_height)
417
{
418
    uint32_t event;
419
    uint32_t *b;
420
 
421
    if (!sna->kgem.has_secure_batches)
422
        return false;
423
 
424
    b = kgem_get_batch(&sna->kgem);
425
    sna->kgem.nbatch += 17;
426
 
427
    switch (pipe) {
428
    default: assert(0);
429
    case 0: event = 1 << 0; break;
430
    case 1: event = 1 << 8; break;
431
    case 2: event = 1 << 14; break;
432
    }
433
 
434
    b[0] = MI_LOAD_REGISTER_IMM | 1;
435
    b[1] = 0x44050; /* DERRMR */
436
    b[2] = ~event;
437
    b[3] = MI_LOAD_REGISTER_IMM | 1;
438
    b[4] = 0xa188; /* FORCEWAKE_MT */
439
    b[5] = 2 << 16 | 2;
440
 
441
    /* The documentation says that the LOAD_SCAN_LINES command
442
     * always comes in pairs. Don't ask me why. */
443
    switch (pipe) {
444
    default: assert(0);
445
    case 0: event = 0 << 19; break;
446
    case 1: event = 1 << 19; break;
447
    case 2: event = 4 << 19; break;
448
    }
449
    b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event;
450
    b[9] = b[7] = (y1 << 16) | (y2-1);
451
 
452
    switch (pipe) {
453
    default: assert(0);
454
    case 0: event = 1 << 0; break;
455
    case 1: event = 1 << 8; break;
456
    case 2: event = 1 << 14; break;
457
    }
458
    b[10] = MI_WAIT_FOR_EVENT | event;
459
 
460
    b[11] = MI_LOAD_REGISTER_IMM | 1;
461
    b[12] = 0xa188; /* FORCEWAKE_MT */
462
    b[13] = 2 << 16;
463
    b[14] = MI_LOAD_REGISTER_IMM | 1;
464
    b[15] = 0x44050; /* DERRMR */
465
    b[16] = ~0;
466
 
467
    sna->kgem.batch_flags |= I915_EXEC_SECURE;
468
    return true;
469
}
470
 
471
 
472
static bool sna_emit_wait_for_scanline_ivb(struct sna *sna,
473
                        rect_t *crtc,
474
                        int pipe, int y1, int y2,
475
                        bool full_height)
476
{
477
    uint32_t *b;
478
    uint32_t event;
479
    uint32_t forcewake;
480
 
481
    if (!sna->kgem.has_secure_batches)
482
        return false;
483
 
484
    assert(y1 >= 0);
485
    assert(y2 > y1);
486
    assert(sna->kgem.mode);
487
 
488
    /* Always program one less than the desired value */
489
    if (--y1 < 0)
490
        y1 = crtc->b;
491
    y2--;
492
 
493
    switch (pipe) {
494
    default:
495
        assert(0);
496
    case 0:
497
        event = 1 << (full_height ? 3 : 0);
498
        break;
499
    case 1:
500
        event = 1 << (full_height ? 11 : 8);
501
        break;
502
    case 2:
503
        event = 1 << (full_height ? 21 : 14);
504
        break;
505
    }
506
 
507
    if (sna->kgem.gen == 071)
508
        forcewake = 0x1300b0; /* FORCEWAKE_VLV */
509
    else
510
        forcewake = 0xa188; /* FORCEWAKE_MT */
511
 
512
    b = kgem_get_batch(&sna->kgem);
513
 
514
    /* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */
515
    if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) {
516
        int dw = sna->kgem.nbatch + 6;
517
        dw = ALIGN(dw, 16) - dw;
518
        while (dw--)
519
            *b++ = MI_NOOP;
520
    }
521
 
522
    b[0] = MI_LOAD_REGISTER_IMM | 1;
523
    b[1] = 0x44050; /* DERRMR */
524
    b[2] = ~event;
525
    b[3] = MI_LOAD_REGISTER_IMM | 1;
526
    b[4] = forcewake;
527
    b[5] = 2 << 16 | 2;
528
    b[6] = MI_LOAD_REGISTER_IMM | 1;
529
    b[7] = 0x70068 + 0x1000 * pipe;
530
    b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2;
531
    b[9] = MI_WAIT_FOR_EVENT | event;
532
    b[10] = MI_LOAD_REGISTER_IMM | 1;
533
    b[11] = forcewake;
534
    b[12] = 2 << 16;
535
    b[13] = MI_LOAD_REGISTER_IMM | 1;
536
    b[14] = 0x44050; /* DERRMR */
537
    b[15] = ~0;
538
 
539
    sna->kgem.nbatch = b - sna->kgem.batch + 16;
540
 
541
    sna->kgem.batch_flags |= I915_EXEC_SECURE;
542
    return true;
543
}
544
 
545
 
4372 Serge 546
static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
547
                        rect_t *crtc,
548
					    int pipe, int y1, int y2,
549
					    bool full_height)
4304 Serge 550
{
4372 Serge 551
	uint32_t *b;
552
	uint32_t event;
553
 
554
//	if (!sna->kgem.has_secure_batches)
555
//		return false;
556
 
557
	assert(y1 >= 0);
558
	assert(y2 > y1);
559
	assert(sna->kgem.mode == KGEM_RENDER);
560
 
561
	/* Always program one less than the desired value */
562
	if (--y1 < 0)
563
		y1 = crtc->b;
564
	y2--;
565
 
566
	/* The scanline granularity is 3 bits */
567
	y1 &= ~7;
568
	y2 &= ~7;
569
	if (y2 == y1)
570
		return false;
571
 
572
	event = 1 << (3*full_height + pipe*8);
573
 
574
	b = kgem_get_batch(&sna->kgem);
575
	sna->kgem.nbatch += 10;
576
 
577
	b[0] = MI_LOAD_REGISTER_IMM | 1;
578
	b[1] = 0x44050; /* DERRMR */
579
	b[2] = ~event;
580
	b[3] = MI_LOAD_REGISTER_IMM | 1;
581
	b[4] = 0x4f100; /* magic */
582
	b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2;
583
	b[6] = MI_WAIT_FOR_EVENT | event;
584
	b[7] = MI_LOAD_REGISTER_IMM | 1;
585
	b[8] = 0x44050; /* DERRMR */
586
	b[9] = ~0;
587
 
588
	sna->kgem.batch_flags |= I915_EXEC_SECURE;
589
 
590
	return true;
591
}
592
 
4375 Serge 593
static bool sna_emit_wait_for_scanline_gen4(struct sna *sna,
594
                        rect_t *crtc,
595
                        int pipe, int y1, int y2,
596
                        bool full_height)
597
{
598
    uint32_t event;
599
    uint32_t *b;
600
 
601
    if (pipe == 0) {
602
        if (full_height)
603
            event = MI_WAIT_FOR_PIPEA_SVBLANK;
604
        else
605
            event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
606
    } else {
607
        if (full_height)
608
            event = MI_WAIT_FOR_PIPEB_SVBLANK;
609
        else
610
            event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
611
    }
612
 
613
    b = kgem_get_batch(&sna->kgem);
614
    sna->kgem.nbatch += 5;
615
 
616
    /* The documentation says that the LOAD_SCAN_LINES command
617
     * always comes in pairs. Don't ask me why. */
618
    b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
619
    b[3] = b[1] = (y1 << 16) | (y2-1);
620
    b[4] = MI_WAIT_FOR_EVENT | event;
621
 
622
    return true;
623
}
624
 
625
static bool sna_emit_wait_for_scanline_gen2(struct sna *sna,
626
                        rect_t *crtc,
627
                        int pipe, int y1, int y2,
628
                        bool full_height)
629
{
630
    uint32_t *b;
631
 
632
    /*
633
     * Pre-965 doesn't have SVBLANK, so we need a bit
634
     * of extra time for the blitter to start up and
635
     * do its job for a full height blit
636
     */
637
    if (full_height)
638
        y2 -= 2;
639
 
640
    b = kgem_get_batch(&sna->kgem);
641
    sna->kgem.nbatch += 5;
642
 
643
    /* The documentation says that the LOAD_SCAN_LINES command
644
     * always comes in pairs. Don't ask me why. */
645
    b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
646
    b[3] = b[1] = (y1 << 16) | (y2-1);
647
    b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe);
648
 
649
    return true;
650
}
651
 
4372 Serge 652
bool
653
sna_wait_for_scanline(struct sna *sna,
654
		      rect_t *crtc,
655
		      rect_t *clip)
656
{
657
	bool full_height;
658
	int y1, y2, pipe;
659
	bool ret;
660
 
661
//	if (sna->flags & SNA_NO_VSYNC)
662
//		return false;
663
 
664
	/*
665
	 * Make sure we don't wait for a scanline that will
666
	 * never occur
667
	 */
668
	y1 = clip->t - crtc->t;
4374 Serge 669
    if (y1 < 1)
670
        y1 = 1;
4372 Serge 671
	y2 = clip->b - crtc->t;
672
	if (y2 > crtc->b - crtc->t)
673
		y2 = crtc->b - crtc->t;
674
//	DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2));
675
//	printf("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2);
676
 
677
	if (y2 <= y1 + 4)
678
		return false;
679
 
680
	full_height = y1 == 0 && y2 == crtc->b - crtc->t;
681
 
4377 Serge 682
    pipe = sna_fb.pipe;
4372 Serge 683
	DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n",
684
	     __FUNCTION__, pipe, y1, y2, full_height));
685
 
686
	if (sna->kgem.gen >= 0100)
687
		ret = false;
4375 Serge 688
    else if (sna->kgem.gen >= 075)
689
        ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
690
    else if (sna->kgem.gen >= 070)
691
        ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
4372 Serge 692
	else if (sna->kgem.gen >= 060)
693
		ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
4375 Serge 694
    else if (sna->kgem.gen >= 040)
695
        ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
696
    else
697
        ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height);
4372 Serge 698
 
699
	return ret;
700
}
701
 
702
 
703
 
704
 
705
 
706
 
707
 
708
 
4501 Serge 709
int intel_get_device_id(struct sna *sna)
710
{
711
    struct drm_i915_getparam gp;
712
    int devid = 0;
4372 Serge 713
 
4501 Serge 714
    memset(&gp, 0, sizeof(gp));
715
    gp.param = I915_PARAM_CHIPSET_ID;
716
    gp.value = &devid;
717
 
718
    if (drmIoctl(sna->scrn, DRM_IOCTL_I915_GETPARAM, &gp))
719
        return 0;
720
    return devid;
721
}
722
 
4372 Serge 723
static const struct intel_device_info intel_generic_info = {
724
	.gen = -1,
725
};
726
 
727
static const struct intel_device_info intel_i915_info = {
728
	.gen = 030,
729
};
730
static const struct intel_device_info intel_i945_info = {
731
	.gen = 031,
732
};
733
 
734
static const struct intel_device_info intel_g33_info = {
735
	.gen = 033,
736
};
737
 
738
static const struct intel_device_info intel_i965_info = {
739
	.gen = 040,
740
};
741
 
742
static const struct intel_device_info intel_g4x_info = {
743
	.gen = 045,
744
};
745
 
746
static const struct intel_device_info intel_ironlake_info = {
747
	.gen = 050,
748
};
749
 
750
static const struct intel_device_info intel_sandybridge_info = {
751
	.gen = 060,
752
};
753
 
754
static const struct intel_device_info intel_ivybridge_info = {
755
	.gen = 070,
756
};
757
 
758
static const struct intel_device_info intel_valleyview_info = {
759
	.gen = 071,
760
};
761
 
762
static const struct intel_device_info intel_haswell_info = {
763
	.gen = 075,
764
};
765
 
766
#define INTEL_DEVICE_MATCH(d,i) \
767
    { 0x8086, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0x3 << 16, 0xff << 16, (intptr_t)(i) }
768
 
769
 
770
static const struct pci_id_match intel_device_match[] = {
771
 
772
	INTEL_I915G_IDS(&intel_i915_info),
773
	INTEL_I915GM_IDS(&intel_i915_info),
774
	INTEL_I945G_IDS(&intel_i945_info),
775
	INTEL_I945GM_IDS(&intel_i945_info),
776
 
777
	INTEL_G33_IDS(&intel_g33_info),
778
	INTEL_PINEVIEW_IDS(&intel_g33_info),
779
 
780
	INTEL_I965G_IDS(&intel_i965_info),
781
	INTEL_I965GM_IDS(&intel_i965_info),
782
 
783
	INTEL_G45_IDS(&intel_g4x_info),
784
	INTEL_GM45_IDS(&intel_g4x_info),
785
 
786
	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
787
	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
788
 
789
	INTEL_SNB_D_IDS(&intel_sandybridge_info),
790
	INTEL_SNB_M_IDS(&intel_sandybridge_info),
791
 
792
	INTEL_IVB_D_IDS(&intel_ivybridge_info),
793
	INTEL_IVB_M_IDS(&intel_ivybridge_info),
794
 
795
	INTEL_HSW_D_IDS(&intel_haswell_info),
796
	INTEL_HSW_M_IDS(&intel_haswell_info),
797
 
798
	INTEL_VLV_D_IDS(&intel_valleyview_info),
799
	INTEL_VLV_M_IDS(&intel_valleyview_info),
800
 
801
	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
802
 
803
	{ 0, 0, 0 },
804
};
805
 
806
const struct pci_id_match *PciDevMatch(uint16_t dev,const struct pci_id_match *list)
807
{
808
    while(list->device_id)
809
    {
810
        if(dev==list->device_id)
811
            return list;
812
        list++;
813
    }
814
    return NULL;
815
}
816
 
817
const struct intel_device_info *
818
intel_detect_chipset(struct pci_device *pci)
819
{
820
    const struct pci_id_match *ent = NULL;
821
 
822
    ent = PciDevMatch(pci->device_id, intel_device_match);
823
 
824
    if(ent != NULL)
825
        return (const struct intel_device_info*)ent->match_data;
826
    else
827
        return &intel_generic_info;
828
}
829
 
830
int drmIoctl(int fd, unsigned long request, void *arg)
831
{
832
    ioctl_t  io;
833
 
834
    io.handle   = fd;
835
    io.io_code  = request;
836
    io.input    = arg;
837
    io.inp_size = 64;
838
    io.output   = NULL;
839
    io.out_size = 0;
840
 
841
    return call_service(&io);
842
}
843
 
844
 
845
 
846
bool
847
gen6_composite(struct sna *sna,
848
              uint8_t op,
849
              PixmapPtr src, struct kgem_bo *src_bo,
850
              PixmapPtr mask,struct kgem_bo *mask_bo,
851
              PixmapPtr dst, struct kgem_bo *dst_bo,
852
              int32_t src_x, int32_t src_y,
853
              int32_t msk_x, int32_t msk_y,
854
              int32_t dst_x, int32_t dst_y,
855
              int32_t width, int32_t height,
856
              struct sna_composite_op *tmp);
857
 
858
//#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
859
 
860
 
861
int sna_bitmap_from_handle(bitmap_t *bitmap, uint32_t handle)
862
{
4304 Serge 863
    surface_t *sf;
4372 Serge 864
    struct kgem_bo *bo;
4304 Serge 865
 
866
    sf = malloc(sizeof(*sf));
867
    if(sf == NULL)
868
        goto err_1;
869
 
870
    __lock_acquire_recursive(__sna_lock);
871
 
4372 Serge 872
    bo = kgem_bo_from_handle(&sna_device->kgem, handle, bitmap->pitch, bitmap->height);
4304 Serge 873
 
4372 Serge 874
    __lock_release_recursive(__sna_lock);
4304 Serge 875
 
876
    sf->width   = bitmap->width;
877
    sf->height  = bitmap->height;
4372 Serge 878
    sf->data    = NULL;
4304 Serge 879
    sf->pitch   = bo->pitch;
880
    sf->bo      = bo;
881
    sf->bo_size = PAGE_SIZE * bo->size.pages.count;
882
    sf->flags   = bitmap->flags;
883
 
884
    bitmap->handle = (uint32_t)sf;
885
 
886
    return 0;
887
 
888
err_2:
889
    __lock_release_recursive(__sna_lock);
890
    free(sf);
891
err_1:
892
    return -1;
893
};
894
 
4372 Serge 895
void sna_set_bo_handle(bitmap_t *bitmap, int handle)
4304 Serge 896
{
4372 Serge 897
    surface_t *sf = to_surface(bitmap);
898
    struct kgem_bo *bo = sf->bo;
899
    bo->handle = handle;
900
}
901
 
902
static int sna_create_bitmap(bitmap_t *bitmap)
903
{
4304 Serge 904
    surface_t *sf;
4372 Serge 905
    struct kgem_bo *bo;
4304 Serge 906
 
907
    sf = malloc(sizeof(*sf));
908
    if(sf == NULL)
909
        goto err_1;
910
 
911
    __lock_acquire_recursive(__sna_lock);
912
 
4372 Serge 913
    bo = kgem_create_2d(&sna_device->kgem, bitmap->width, bitmap->height,
914
                        32,I915_TILING_NONE, CREATE_CPU_MAP);
4304 Serge 915
 
4372 Serge 916
    if(bo == NULL)
917
        goto err_2;
4304 Serge 918
 
4372 Serge 919
    void *map = kgem_bo_map(&sna_device->kgem, bo);
920
    if(map == NULL)
921
        goto err_3;
922
 
4304 Serge 923
    sf->width   = bitmap->width;
924
    sf->height  = bitmap->height;
4372 Serge 925
    sf->data    = map;
4304 Serge 926
    sf->pitch   = bo->pitch;
927
    sf->bo      = bo;
928
    sf->bo_size = PAGE_SIZE * bo->size.pages.count;
929
    sf->flags   = bitmap->flags;
930
 
931
    bitmap->handle = (uint32_t)sf;
4372 Serge 932
    __lock_release_recursive(__sna_lock);
4304 Serge 933
 
934
    return 0;
935
 
4372 Serge 936
err_3:
937
    kgem_bo_destroy(&sna_device->kgem, bo);
4304 Serge 938
err_2:
939
    __lock_release_recursive(__sna_lock);
940
    free(sf);
941
err_1:
942
    return -1;
943
};
944
 
4372 Serge 945
static int sna_destroy_bitmap(bitmap_t *bitmap)
4304 Serge 946
{
947
    surface_t *sf = to_surface(bitmap);
948
 
949
    __lock_acquire_recursive(__sna_lock);
950
 
951
    kgem_bo_destroy(&sna_device->kgem, sf->bo);
952
 
953
    __lock_release_recursive(__sna_lock);
954
 
955
    free(sf);
956
 
957
    bitmap->handle = -1;
958
    bitmap->data   = (void*)-1;
959
    bitmap->pitch  = -1;
960
 
961
    return 0;
962
};
963
 
4372 Serge 964
static int sna_lock_bitmap(bitmap_t *bitmap)
4304 Serge 965
{
966
    surface_t *sf = to_surface(bitmap);
967
 
968
//    printf("%s\n", __FUNCTION__);
969
    __lock_acquire_recursive(__sna_lock);
970
 
971
    kgem_bo_sync__cpu(&sna_device->kgem, sf->bo);
972
 
973
    __lock_release_recursive(__sna_lock);
974
 
975
    bitmap->data  = sf->data;
976
    bitmap->pitch = sf->pitch;
977
 
978
    return 0;
979
};
980
 
4372 Serge 981
static int sna_resize_bitmap(bitmap_t *bitmap)
4304 Serge 982
{
983
    surface_t *sf = to_surface(bitmap);
984
    struct kgem *kgem = &sna_device->kgem;
985
    struct kgem_bo *bo = sf->bo;
986
 
987
    uint32_t   size;
988
    uint32_t   pitch;
989
 
4372 Serge 990
    bitmap->pitch = -1;
4304 Serge 991
    bitmap->data = (void *) -1;
992
 
4372 Serge 993
    size = kgem_surface_size(kgem,kgem->has_relaxed_fencing, CREATE_CPU_MAP,
994
                 bitmap->width, bitmap->height, 32, I915_TILING_NONE, &pitch);
995
    assert(size && size <= kgem->max_object_size);
4304 Serge 996
 
997
    if(sf->bo_size >= size)
998
    {
999
        sf->width   = bitmap->width;
1000
        sf->height  = bitmap->height;
1001
        sf->pitch   = pitch;
1002
        bo->pitch   = pitch;
1003
 
4372 Serge 1004
        return 0;
4304 Serge 1005
    }
1006
    else
1007
    {
1008
        __lock_acquire_recursive(__sna_lock);
1009
 
1010
        sna_bo_destroy(kgem, bo);
1011
 
1012
        sf->bo = NULL;
1013
 
1014
        bo = kgem_create_2d(kgem, bitmap->width, bitmap->height,
1015
                            32, I915_TILING_NONE, CREATE_CPU_MAP);
1016
 
1017
        if(bo == NULL)
1018
        {
1019
            __lock_release_recursive(__sna_lock);
1020
            return -1;
1021
        };
1022
 
1023
        void *map = kgem_bo_map(kgem, bo);
1024
        if(map == NULL)
1025
        {
1026
            sna_bo_destroy(kgem, bo);
1027
            __lock_release_recursive(__sna_lock);
1028
            return -1;
1029
        };
1030
 
1031
        __lock_release_recursive(__sna_lock);
1032
 
1033
        sf->width   = bitmap->width;
1034
        sf->height  = bitmap->height;
1035
        sf->data    = map;
1036
        sf->pitch   = bo->pitch;
1037
        sf->bo      = bo;
1038
        sf->bo_size = PAGE_SIZE * bo->size.pages.count;
1039
    }
1040
 
1041
    return 0;
1042
};
1043
 
1044
 
1045
 
1046
int sna_create_mask()
1047
{
4372 Serge 1048
    struct kgem_bo *bo;
4304 Serge 1049
 
1050
//    printf("%s width %d height %d\n", __FUNCTION__, sna_fb.width, sna_fb.height);
1051
 
1052
    __lock_acquire_recursive(__sna_lock);
1053
 
1054
    bo = kgem_create_2d(&sna_device->kgem, sna_fb.width, sna_fb.height,
1055
                        8,I915_TILING_NONE, CREATE_CPU_MAP);
1056
 
1057
    if(unlikely(bo == NULL))
1058
        goto err_1;
1059
 
1060
    int *map = kgem_bo_map(&sna_device->kgem, bo);
1061
    if(map == NULL)
1062
        goto err_2;
1063
 
1064
    __lock_release_recursive(__sna_lock);
1065
 
1066
    memset(map, 0, bo->pitch * sna_fb.height);
1067
 
1068
    tls_set(tls_mask, bo);
1069
 
1070
    return 0;
1071
 
1072
err_2:
1073
    kgem_bo_destroy(&sna_device->kgem, bo);
1074
err_1:
1075
    __lock_release_recursive(__sna_lock);
1076
    return -1;
1077
};
1078
 
1079
 
4368 Serge 1080
 
4377 Serge 1081
int sna_blit_tex(bitmap_t *bitmap, int scale, int vsync,
1082
                 int dst_x, int dst_y,int w, int h, int src_x, int src_y)
4304 Serge 1083
 
1084
{
1085
    surface_t *sf = to_surface(bitmap);
1086
 
1087
    struct drm_i915_mask_update update;
1088
 
1089
    struct sna_composite_op composite;
1090
    struct _Pixmap src, dst, mask;
1091
    struct kgem_bo *src_bo, *mask_bo;
1092
    int winx, winy;
1093
 
1094
    char proc_info[1024];
1095
 
1096
    get_proc_info(proc_info);
1097
 
1098
    winx = *(uint32_t*)(proc_info+34);
1099
    winy = *(uint32_t*)(proc_info+38);
1100
//    winw = *(uint32_t*)(proc_info+42)+1;
1101
//    winh = *(uint32_t*)(proc_info+46)+1;
1102
 
1103
    mask_bo = tls_get(tls_mask);
1104
 
1105
    if(unlikely(mask_bo == NULL))
1106
    {
1107
        sna_create_mask();
1108
        mask_bo = tls_get(tls_mask);
1109
        if( mask_bo == NULL)
1110
            return -1;
1111
    };
1112
 
1113
    if(kgem_update_fb(&sna_device->kgem, &sna_fb))
1114
    {
1115
        __lock_acquire_recursive(__sna_lock);
1116
        kgem_bo_destroy(&sna_device->kgem, mask_bo);
1117
        __lock_release_recursive(__sna_lock);
1118
 
1119
        sna_create_mask();
1120
        mask_bo = tls_get(tls_mask);
1121
        if( mask_bo == NULL)
1122
            return -1;
1123
    }
1124
 
1125
    VG_CLEAR(update);
4372 Serge 1126
    update.handle = mask_bo->handle;
1127
    update.bo_map = (int)kgem_bo_map__cpu(&sna_device->kgem, mask_bo);
1128
    drmIoctl(sna_device->kgem.fd, SRV_MASK_UPDATE, &update);
4304 Serge 1129
    mask_bo->pitch = update.bo_pitch;
1130
 
1131
    memset(&src, 0, sizeof(src));
1132
    memset(&dst, 0, sizeof(dst));
1133
    memset(&mask, 0, sizeof(dst));
1134
 
1135
    src.drawable.bitsPerPixel = 32;
1136
 
1137
    src.drawable.width  = sf->width;
1138
    src.drawable.height = sf->height;
1139
 
1140
    dst.drawable.bitsPerPixel = 32;
1141
    dst.drawable.width  = sna_fb.width;
1142
    dst.drawable.height = sna_fb.height;
1143
 
1144
    mask.drawable.bitsPerPixel = 8;
1145
    mask.drawable.width  = update.width;
1146
    mask.drawable.height = update.height;
1147
 
1148
    memset(&composite, 0, sizeof(composite));
1149
 
1150
    src_bo = sf->bo;
1151
 
1152
    __lock_acquire_recursive(__sna_lock);
1153
 
4377 Serge 1154
    if(vsync)
4368 Serge 1155
    {
1156
        rect_t crtc, clip;
4304 Serge 1157
 
4368 Serge 1158
        crtc.l = 0;
1159
        crtc.t = 0;
1160
        crtc.r = sna_fb.width-1;
1161
        crtc.b = sna_fb.height-1;
1162
 
1163
        clip.l = winx+dst_x;
1164
        clip.t = winy+dst_y;
1165
        clip.r = clip.l+w-1;
1166
        clip.b = clip.t+h-1;
1167
 
1168
        kgem_set_mode(&sna_device->kgem, KGEM_RENDER, sna_fb.fb_bo);
1169
        sna_wait_for_scanline(sna_device, &crtc, &clip);
1170
    }
1171
 
4304 Serge 1172
    if( sna_device->render.blit_tex(sna_device, PictOpSrc,scale,
4372 Serge 1173
              &src, src_bo,
1174
              &mask, mask_bo,
1175
              &dst, sna_fb.fb_bo,
4304 Serge 1176
              src_x, src_y,
1177
              dst_x, dst_y,
1178
              winx+dst_x, winy+dst_y,
1179
              w, h,
1180
              &composite) )
1181
    {
4372 Serge 1182
        struct sna_composite_rectangles r;
4304 Serge 1183
 
4372 Serge 1184
        r.src.x = src_x;
1185
        r.src.y = src_y;
1186
        r.mask.x = dst_x;
1187
        r.mask.y = dst_y;
1188
        r.dst.x = winx+dst_x;
1189
        r.dst.y = winy+dst_y;
1190
        r.width  = w;
1191
        r.height = h;
4304 Serge 1192
 
1193
        composite.blt(sna_device, &composite, &r);
1194
        composite.done(sna_device, &composite);
1195
 
1196
    };
1197
 
1198
    kgem_submit(&sna_device->kgem);
1199
 
1200
    __lock_release_recursive(__sna_lock);
1201
 
1202
    bitmap->data   = (void*)-1;
1203
    bitmap->pitch  = -1;
1204
 
1205
    return 0;
1206
}
1207
 
1208
 
4372 Serge 1209
static void sna_fini()
1210
{
1211
    if( sna_device )
1212
    {
1213
        struct kgem_bo *mask;
4304 Serge 1214
 
4372 Serge 1215
        __lock_acquire_recursive(__sna_lock);
4304 Serge 1216
 
4372 Serge 1217
        mask = tls_get(tls_mask);
4304 Serge 1218
 
4372 Serge 1219
        sna_device->render.fini(sna_device);
1220
        if(mask)
1221
            kgem_bo_destroy(&sna_device->kgem, mask);
1222
//        kgem_close_batches(&sna_device->kgem);
1223
        kgem_cleanup_cache(&sna_device->kgem);
4304 Serge 1224
 
4372 Serge 1225
        sna_device = NULL;
1226
        __lock_release_recursive(__sna_lock);
1227
    };
1228
}
4304 Serge 1229
 
4372 Serge 1230
uint32_t DrvInit(uint32_t service, struct pix_driver *driver)
1231
{
1232
    ioctl_t   io;
1233
    int caps = 0;
4304 Serge 1234
 
4372 Serge 1235
    static struct pci_device device;
1236
    struct sna *sna;
4304 Serge 1237
 
4372 Serge 1238
    DBG(("%s\n", __FUNCTION__));
4304 Serge 1239
 
4372 Serge 1240
    __lock_acquire_recursive(__sna_lock);
4304 Serge 1241
 
4372 Serge 1242
    if(sna_device)
1243
        goto done;
4304 Serge 1244
 
4372 Serge 1245
    io.handle   = service;
1246
    io.io_code  = SRV_GET_PCI_INFO;
1247
    io.input    = &device;
1248
    io.inp_size = sizeof(device);
1249
    io.output   = NULL;
1250
    io.out_size = 0;
4304 Serge 1251
 
4372 Serge 1252
    if (call_service(&io)!=0)
1253
        goto err1;
4304 Serge 1254
 
4372 Serge 1255
    sna = malloc(sizeof(*sna));
1256
    if (sna == NULL)
1257
        goto err1;
4304 Serge 1258
 
4372 Serge 1259
    memset(sna, 0, sizeof(*sna));
4304 Serge 1260
 
4372 Serge 1261
    sna->cpu_features = sna_cpu_detect();
4304 Serge 1262
 
4372 Serge 1263
    sna->PciInfo = &device;
1264
    sna->info = intel_detect_chipset(sna->PciInfo);
1265
    sna->scrn = service;
4304 Serge 1266
 
4372 Serge 1267
    kgem_init(&sna->kgem, service, sna->PciInfo, sna->info->gen);
4304 Serge 1268
 
4372 Serge 1269
    /* Disable tiling by default */
1270
    sna->tiling = 0;
4304 Serge 1271
 
4372 Serge 1272
    /* Default fail-safe value of 75 Hz */
1273
//    sna->vblank_interval = 1000 * 1000 * 1000 / 75;
4304 Serge 1274
 
4372 Serge 1275
    sna->flags = 0;
4304 Serge 1276
 
4372 Serge 1277
    sna_accel_init(sna);
4304 Serge 1278
 
4372 Serge 1279
    tls_mask = tls_alloc();
4304 Serge 1280
 
4372 Serge 1281
//    printf("tls mask %x\n", tls_mask);
4304 Serge 1282
 
4372 Serge 1283
    driver->create_bitmap  = sna_create_bitmap;
1284
    driver->destroy_bitmap = sna_destroy_bitmap;
1285
    driver->lock_bitmap    = sna_lock_bitmap;
1286
    driver->blit           = sna_blit_tex;
1287
    driver->resize_bitmap  = sna_resize_bitmap;
1288
    driver->fini           = sna_fini;
1289
done:
1290
    caps = sna_device->render.caps;
4304 Serge 1291
 
4372 Serge 1292
err1:
1293
    __lock_release_recursive(__sna_lock);
4304 Serge 1294
 
4372 Serge 1295
    return caps;
4304 Serge 1296
}
1297
 
1298
 
1299