Initial code release
[adaptation/xorg-x11-drv-intel.git] / src / intel_uxa.c
1 /**************************************************************************
2
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 All Rights Reserved.
5 Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org>
6   Based on code from i830_xaa.c.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sub license, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
18 of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "xf86.h"
35 #include "xaarop.h"
36 #include "intel.h"
37 #include "i830_reg.h"
38 #include "i915_drm.h"
39 #include "brw_defines.h"
40 #include <string.h>
41 #include <errno.h>
42
43 static const int I830CopyROP[16] = {
44         ROP_0,                  /* GXclear */
45         ROP_DSa,                /* GXand */
46         ROP_SDna,               /* GXandReverse */
47         ROP_S,                  /* GXcopy */
48         ROP_DSna,               /* GXandInverted */
49         ROP_D,                  /* GXnoop */
50         ROP_DSx,                /* GXxor */
51         ROP_DSo,                /* GXor */
52         ROP_DSon,               /* GXnor */
53         ROP_DSxn,               /* GXequiv */
54         ROP_Dn,                 /* GXinvert */
55         ROP_SDno,               /* GXorReverse */
56         ROP_Sn,                 /* GXcopyInverted */
57         ROP_DSno,               /* GXorInverted */
58         ROP_DSan,               /* GXnand */
59         ROP_1                   /* GXset */
60 };
61
62 static const int I830PatternROP[16] = {
63         ROP_0,
64         ROP_DPa,
65         ROP_PDna,
66         ROP_P,
67         ROP_DPna,
68         ROP_D,
69         ROP_DPx,
70         ROP_DPo,
71         ROP_DPon,
72         ROP_PDxn,
73         ROP_Dn,
74         ROP_PDno,
75         ROP_Pn,
76         ROP_DPno,
77         ROP_DPan,
78         ROP_1
79 };
80
81 #if HAS_DEVPRIVATEKEYREC
82 DevPrivateKeyRec uxa_pixmap_index;
83 #else
84 int uxa_pixmap_index;
85 #endif
86
87 static void
88 gen6_context_switch(intel_screen_private *intel,
89                     int new_mode)
90 {
91         intel_batch_submit(intel->scrn);
92 }
93
94 static void
95 gen5_context_switch(intel_screen_private *intel,
96                     int new_mode)
97 {
98         /* Ironlake has a limitation that a 3D or Media command can't
99          * be the first command after a BLT, unless it's
100          * non-pipelined.  Instead of trying to track it and emit a
101          * command at the right time, we just emit a dummy
102          * non-pipelined 3D instruction after each blit.
103          */
104
105         if (new_mode == I915_EXEC_BLT) {
106                 OUT_BATCH(MI_FLUSH |
107                           MI_STATE_INSTRUCTION_CACHE_FLUSH |
108                           MI_INHIBIT_RENDER_CACHE_FLUSH);
109         } else {
110                 OUT_BATCH(CMD_POLY_STIPPLE_OFFSET << 16);
111                 OUT_BATCH(0);
112         }
113 }
114
115 static void
116 gen4_context_switch(intel_screen_private *intel,
117                     int new_mode)
118 {
119         if (new_mode == I915_EXEC_BLT) {
120                 OUT_BATCH(MI_FLUSH |
121                           MI_STATE_INSTRUCTION_CACHE_FLUSH |
122                           MI_INHIBIT_RENDER_CACHE_FLUSH);
123         }
124 }
125
126 Bool
127 intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
128                          int num_bos)
129 {
130         intel_screen_private *intel = intel_get_screen_private(scrn);
131
132         if (intel->batch_bo == NULL) {
133                 intel_debug_fallback(scrn, "VT inactive\n");
134                 return FALSE;
135         }
136
137         bo_table[0] = intel->batch_bo;
138         if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) {
139                 intel_batch_submit(scrn);
140                 bo_table[0] = intel->batch_bo;
141                 if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) !=
142                     0) {
143                         intel_debug_fallback(scrn, "Couldn't get aperture "
144                                             "space for BOs\n");
145                         return FALSE;
146                 }
147         }
148         return TRUE;
149 }
150
151 static unsigned int
152 intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
153                               int w, int h,
154                               uint32_t *tiling,
155                               int *stride,
156                               unsigned usage)
157 {
158         ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
159         intel_screen_private *intel = intel_get_screen_private(scrn);
160         int pitch, size;
161
162         if (*tiling != I915_TILING_NONE) {
163                 /* First check whether tiling is necessary. */
164                 pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
165                 pitch = ALIGN(pitch, 64);
166                 size = pitch * ALIGN (h, 2);
167                 if (INTEL_INFO(intel)->gen < 40) {
168                         /* Gen 2/3 has a maximum stride for tiling of
169                          * 8192 bytes.
170                          */
171                         if (pitch > KB(8))
172                                 *tiling = I915_TILING_NONE;
173
174                         /* Narrower than half a tile? */
175                         if (pitch < 256)
176                                 *tiling = I915_TILING_NONE;
177
178                         /* Older hardware requires fences to be pot size
179                          * aligned with a minimum of 1 MiB, so causes
180                          * massive overallocation for small textures.
181                          */
182                         if (size < 1024*1024/2 && !intel->has_relaxed_fencing)
183                                 *tiling = I915_TILING_NONE;
184                 } else if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && size <= 4096) {
185                         /* Disable tiling beneath a page size, we will not see
186                          * any benefit from reducing TLB misses and instead
187                          * just incur extra cost when we require a fence.
188                          */
189                         *tiling = I915_TILING_NONE;
190                 }
191         }
192
193         pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
194         if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256)
195                 *tiling = I915_TILING_NONE;
196
197         if (*tiling != I915_TILING_NONE) {
198                 int aligned_h, tile_height;
199
200                 if (IS_GEN2(intel))
201                         tile_height = 16;
202                 else if (*tiling == I915_TILING_X)
203                         tile_height = 8;
204                 else
205                         tile_height = 32;
206                 aligned_h = ALIGN(h, tile_height);
207
208                 *stride = intel_get_fence_pitch(intel,
209                                                 ALIGN(pitch, 512),
210                                                 *tiling);
211
212                 /* Round the object up to the size of the fence it will live in
213                  * if necessary.  We could potentially make the kernel allocate
214                  * a larger aperture space and just bind the subset of pages in,
215                  * but this is easier and also keeps us out of trouble (as much)
216                  * with drm_intel_bufmgr_check_aperture().
217                  */
218                 size = intel_get_fence_size(intel, *stride * aligned_h);
219
220                 if (size > intel->max_tiling_size)
221                         *tiling = I915_TILING_NONE;
222         }
223
224         if (*tiling == I915_TILING_NONE) {
225                 /* Round the height up so that the GPU's access to a 2x2 aligned
226                  * subspan doesn't address an invalid page offset beyond the
227                  * end of the GTT.
228                  */
229                 *stride = ALIGN(pitch, 64);
230                 size = *stride * ALIGN(h, 2);
231         }
232
233         return size;
234 }
235
236 static Bool
237 intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
238 {
239         ScrnInfoPtr scrn = xf86Screens[drawable->pScreen->myNum];
240
241         if (!UXA_PM_IS_SOLID(drawable, planemask)) {
242                 intel_debug_fallback(scrn, "planemask is not solid\n");
243                 return FALSE;
244         }
245
246         switch (drawable->bitsPerPixel) {
247         case 8:
248         case 16:
249         case 32:
250                 break;
251         default:
252                 return FALSE;
253         }
254
255         return TRUE;
256 }
257
258 /**
259  * Sets up hardware state for a series of solid fills.
260  */
261 static Bool
262 intel_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
263 {
264         ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
265         intel_screen_private *intel = intel_get_screen_private(scrn);
266         drm_intel_bo *bo_table[] = {
267                 NULL,           /* batch_bo */
268                 intel_get_pixmap_bo(pixmap),
269         };
270
271         if (!intel_check_pitch_2d(pixmap))
272                 return FALSE;
273
274         if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
275                 return FALSE;
276
277         intel->BR[13] = (I830PatternROP[alu] & 0xff) << 16;
278         switch (pixmap->drawable.bitsPerPixel) {
279         case 8:
280                 break;
281         case 16:
282                 /* RGB565 */
283                 intel->BR[13] |= (1 << 24);
284                 break;
285         case 32:
286                 /* RGB8888 */
287                 intel->BR[13] |= ((1 << 24) | (1 << 25));
288                 break;
289         }
290         intel->BR[16] = fg;
291
292         return TRUE;
293 }
294
295 static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
296 {
297         ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
298         intel_screen_private *intel = intel_get_screen_private(scrn);
299         unsigned long pitch;
300         uint32_t cmd;
301
302         if (x1 < 0)
303                 x1 = 0;
304         if (y1 < 0)
305                 y1 = 0;
306         if (x2 > pixmap->drawable.width)
307                 x2 = pixmap->drawable.width;
308         if (y2 > pixmap->drawable.height)
309                 y2 = pixmap->drawable.height;
310
311         if (x2 <= x1 || y2 <= y1)
312                 return;
313
314         pitch = intel_pixmap_pitch(pixmap);
315
316         {
317                 BEGIN_BATCH_BLT(6);
318
319                 cmd = XY_COLOR_BLT_CMD;
320
321                 if (pixmap->drawable.bitsPerPixel == 32)
322                         cmd |=
323                             XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
324
325                 if (INTEL_INFO(intel)->gen >= 40 && intel_pixmap_tiled(pixmap)) {
326                         assert((pitch % 512) == 0);
327                         pitch >>= 2;
328                         cmd |= XY_COLOR_BLT_TILED;
329                 }
330
331                 OUT_BATCH(cmd);
332
333                 OUT_BATCH(intel->BR[13] | pitch);
334                 OUT_BATCH((y1 << 16) | (x1 & 0xffff));
335                 OUT_BATCH((y2 << 16) | (x2 & 0xffff));
336                 OUT_RELOC_PIXMAP_FENCED(pixmap, I915_GEM_DOMAIN_RENDER,
337                                         I915_GEM_DOMAIN_RENDER, 0);
338                 OUT_BATCH(intel->BR[16]);
339                 ADVANCE_BATCH();
340         }
341 }
342
343 static void intel_uxa_done_solid(PixmapPtr pixmap)
344 {
345         ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
346
347         intel_debug_flush(scrn);
348 }
349
350 /**
351  * TODO:
352  *   - support planemask using FULL_BLT_CMD?
353  */
354 static Bool
355 intel_uxa_check_copy(PixmapPtr source, PixmapPtr dest,
356                     int alu, Pixel planemask)
357 {
358         ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
359
360         if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) {
361                 intel_debug_fallback(scrn, "planemask is not solid");
362                 return FALSE;
363         }
364
365         if (source->drawable.bitsPerPixel != dest->drawable.bitsPerPixel) {
366                 intel_debug_fallback(scrn, "mixed bpp copies unsupported\n");
367                 return FALSE;
368         }
369         switch (source->drawable.bitsPerPixel) {
370         case 8:
371         case 16:
372         case 32:
373                 break;
374         default:
375                 return FALSE;
376         }
377
378         if (!intel_check_pitch_2d(source))
379                 return FALSE;
380         if (!intel_check_pitch_2d(dest))
381                 return FALSE;
382
383         return TRUE;
384 }
385
386 static Bool
387 intel_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
388                       int ydir, int alu, Pixel planemask)
389 {
390         ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
391         intel_screen_private *intel = intel_get_screen_private(scrn);
392         drm_intel_bo *bo_table[] = {
393                 NULL,           /* batch_bo */
394                 intel_get_pixmap_bo(source),
395                 intel_get_pixmap_bo(dest),
396         };
397
398         if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
399                 return FALSE;
400
401         intel->render_source = source;
402
403         intel->BR[13] = I830CopyROP[alu] << 16;
404         switch (source->drawable.bitsPerPixel) {
405         case 8:
406                 break;
407         case 16:
408                 intel->BR[13] |= (1 << 24);
409                 break;
410         case 32:
411                 intel->BR[13] |= ((1 << 25) | (1 << 24));
412                 break;
413         }
414
415         return TRUE;
416 }
417
418 static void
419 intel_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
420               int dst_y1, int w, int h)
421 {
422         ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
423         intel_screen_private *intel = intel_get_screen_private(scrn);
424         uint32_t cmd;
425         int dst_x2, dst_y2, src_x2, src_y2;
426         unsigned int dst_pitch, src_pitch;
427
428         dst_x2 = dst_x1 + w;
429         dst_y2 = dst_y1 + h;
430
431         /* XXX Fixup extents as a lamentable workaround for missing
432          * source clipping in the upper layers.
433          */
434         if (dst_x1 < 0)
435                 src_x1 -= dst_x1, dst_x1 = 0;
436         if (dst_y1 < 0)
437                 src_y1 -= dst_y1, dst_y1 = 0;
438         if (dst_x2 > dest->drawable.width)
439                 dst_x2 = dest->drawable.width;
440         if (dst_y2 > dest->drawable.height)
441                 dst_y2 = dest->drawable.height;
442
443         src_x2 = src_x1 + (dst_x2 - dst_x1);
444         src_y2 = src_y1 + (dst_y2 - dst_y1);
445
446         if (src_x1 < 0)
447                 dst_x1 -= src_x1, src_x1 = 0;
448         if (src_y1 < 0)
449                 dst_y1 -= src_y1, src_y1 = 0;
450         if (src_x2 > intel->render_source->drawable.width)
451                 dst_x2 -= src_x2 - intel->render_source->drawable.width;
452         if (src_y2 > intel->render_source->drawable.height)
453                 dst_y2 -= src_y2 - intel->render_source->drawable.height;
454
455         if (dst_x2 <= dst_x1 || dst_y2 <= dst_y1)
456                 return;
457
458         dst_pitch = intel_pixmap_pitch(dest);
459         src_pitch = intel_pixmap_pitch(intel->render_source);
460
461         {
462                 BEGIN_BATCH_BLT(8);
463
464                 cmd = XY_SRC_COPY_BLT_CMD;
465
466                 if (dest->drawable.bitsPerPixel == 32)
467                         cmd |=
468                             XY_SRC_COPY_BLT_WRITE_ALPHA |
469                             XY_SRC_COPY_BLT_WRITE_RGB;
470
471                 if (INTEL_INFO(intel)->gen >= 40) {
472                         if (intel_pixmap_tiled(dest)) {
473                                 assert((dst_pitch % 512) == 0);
474                                 dst_pitch >>= 2;
475                                 cmd |= XY_SRC_COPY_BLT_DST_TILED;
476                         }
477
478                         if (intel_pixmap_tiled(intel->render_source)) {
479                                 assert((src_pitch % 512) == 0);
480                                 src_pitch >>= 2;
481                                 cmd |= XY_SRC_COPY_BLT_SRC_TILED;
482                         }
483                 }
484
485                 OUT_BATCH(cmd);
486
487                 OUT_BATCH(intel->BR[13] | dst_pitch);
488                 OUT_BATCH((dst_y1 << 16) | (dst_x1 & 0xffff));
489                 OUT_BATCH((dst_y2 << 16) | (dst_x2 & 0xffff));
490                 OUT_RELOC_PIXMAP_FENCED(dest,
491                                         I915_GEM_DOMAIN_RENDER,
492                                         I915_GEM_DOMAIN_RENDER,
493                                         0);
494                 OUT_BATCH((src_y1 << 16) | (src_x1 & 0xffff));
495                 OUT_BATCH(src_pitch);
496                 OUT_RELOC_PIXMAP_FENCED(intel->render_source,
497                                         I915_GEM_DOMAIN_RENDER, 0,
498                                         0);
499
500                 ADVANCE_BATCH();
501         }
502 }
503
504 static void intel_uxa_done_copy(PixmapPtr dest)
505 {
506         ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
507
508         intel_debug_flush(scrn);
509 }
510
511 /**
512  * Do any cleanup from the Composite operation.
513  *
514  * This is shared between i830 through i965.
515  */
516 static void i830_done_composite(PixmapPtr dest)
517 {
518         ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
519         intel_screen_private *intel = intel_get_screen_private(scrn);
520
521         if (intel->vertex_flush)
522                 intel->vertex_flush(intel);
523
524         intel_debug_flush(scrn);
525 }
526
527 #define xFixedToFloat(val) \
528         ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
529
530 static Bool
531 _intel_transform_point(PictTransformPtr transform,
532                        float x, float y, float result[3])
533 {
534         int j;
535
536         for (j = 0; j < 3; j++) {
537                 result[j] = (xFixedToFloat(transform->matrix[j][0]) * x +
538                              xFixedToFloat(transform->matrix[j][1]) * y +
539                              xFixedToFloat(transform->matrix[j][2]));
540         }
541         if (!result[2])
542                 return FALSE;
543         return TRUE;
544 }
545
546 /**
547  * Returns the floating-point coordinates transformed by the given transform.
548  *
549  * transform may be null.
550  */
551 Bool
552 intel_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
553                                   float *x_out, float *y_out)
554 {
555         if (transform == NULL) {
556                 *x_out = x;
557                 *y_out = y;
558         } else {
559                 float result[3];
560
561                 if (!_intel_transform_point(transform,
562                                             x, y,
563                                             result))
564                         return FALSE;
565                 *x_out = result[0] / result[2];
566                 *y_out = result[1] / result[2];
567         }
568         return TRUE;
569 }
570
571 /**
572  * Returns the un-normalized floating-point coordinates transformed by the given transform.
573  *
574  * transform may be null.
575  */
576 Bool
577 intel_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
578                                      float *x_out, float *y_out, float *w_out)
579 {
580         if (transform == NULL) {
581                 *x_out = x;
582                 *y_out = y;
583                 *w_out = 1;
584         } else {
585                 float result[3];
586
587                 if (!_intel_transform_point(transform,
588                                             x, y,
589                                             result))
590                         return FALSE;
591                 *x_out = result[0];
592                 *y_out = result[1];
593                 *w_out = result[2];
594         }
595         return TRUE;
596 }
597
598 /**
599  * Returns whether the provided transform is affine.
600  *
601  * transform may be null.
602  */
603 Bool intel_transform_is_affine(PictTransformPtr t)
604 {
605         if (t == NULL)
606                 return TRUE;
607         return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
608 }
609
610 dri_bo *intel_get_pixmap_bo(PixmapPtr pixmap)
611 {
612         struct intel_pixmap *intel;
613
614         intel = intel_get_pixmap_private(pixmap);
615         if (intel == NULL)
616                 return NULL;
617
618         return intel->bo;
619 }
620
621 void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
622 {
623         ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
624         intel_screen_private *intel = intel_get_screen_private(scrn);
625         struct intel_pixmap *priv;
626
627         priv = intel_get_pixmap_private(pixmap);
628
629         if (priv == NULL && bo == NULL)
630             return;
631
632         if (priv != NULL) {
633                 if (priv->bo == bo)
634                         return;
635
636                 priv->dst_bound = priv->src_bound = 0;
637                 if (list_is_empty(&priv->batch)) {
638                         dri_bo_unreference(priv->bo);
639                 } else if (!drm_intel_bo_is_reusable(priv->bo)) {
640                         dri_bo_unreference(priv->bo);
641                         list_del(&priv->batch);
642                         list_del(&priv->flush);
643                 } else {
644                         list_add(&priv->in_flight, &intel->in_flight);
645                         priv = NULL;
646                 }
647
648                 if (intel->render_current_dest == pixmap)
649                     intel->render_current_dest = NULL;
650         }
651
652         if (bo != NULL) {
653                 uint32_t tiling;
654                 uint32_t swizzle_mode;
655                 int ret;
656
657                 if (priv == NULL) {
658                         priv = calloc(1, sizeof (struct intel_pixmap));
659                         if (priv == NULL)
660                                 goto BAIL;
661
662                         list_init(&priv->batch);
663                         list_init(&priv->flush);
664                 }
665
666                 dri_bo_reference(bo);
667                 priv->bo = bo;
668                 priv->stride = intel_pixmap_pitch(pixmap);
669
670                 ret = drm_intel_bo_get_tiling(bo, &tiling, &swizzle_mode);
671                 if (ret != 0) {
672                         FatalError("Couldn't get tiling on bo %p: %s\n",
673                                    bo, strerror(-ret));
674                 }
675
676                 priv->tiling = tiling;
677                 priv->busy = -1;
678                 priv->offscreen = 1;
679         } else {
680                 if (priv != NULL) {
681                         free(priv);
682                         priv = NULL;
683                 }
684         }
685
686   BAIL:
687         intel_set_pixmap_private(pixmap, priv);
688 }
689
690 static Bool intel_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
691 {
692         struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
693         return priv && priv->offscreen;
694 }
695
696 static Bool intel_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
697 {
698         ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
699         intel_screen_private *intel = intel_get_screen_private(scrn);
700         struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
701         dri_bo *bo = priv->bo;
702         int ret;
703
704         if (!list_is_empty(&priv->batch) &&
705             (access == UXA_ACCESS_RW || priv->batch_write))
706                 intel_batch_submit(scrn);
707
708         if (priv->tiling || bo->size <= intel->max_gtt_map_size)
709                 ret = drm_intel_gem_bo_map_gtt(bo);
710         else
711                 ret = dri_bo_map(bo, access == UXA_ACCESS_RW);
712         if (ret) {
713                 xf86DrvMsg(scrn->scrnIndex, X_WARNING,
714                            "%s: bo map failed: %s\n",
715                            __FUNCTION__,
716                            strerror(-ret));
717                 return FALSE;
718         }
719
720         pixmap->devPrivate.ptr = bo->virtual;
721         priv->busy = 0;
722
723         return TRUE;
724 }
725
726 static Bool intel_uxa_pixmap_put_image(PixmapPtr pixmap,
727                                        char *src, int src_pitch,
728                                        int x, int y, int w, int h)
729 {
730         struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
731         int stride = intel_pixmap_pitch(pixmap);
732         int cpp = pixmap->drawable.bitsPerPixel/8;
733         int ret = FALSE;
734
735         if (priv == NULL || priv->bo == NULL)
736                 return FALSE;
737
738         if (priv->tiling == I915_TILING_NONE &&
739             (h == 1 || (src_pitch == stride && w == pixmap->drawable.width))) {
740                 return drm_intel_bo_subdata(priv->bo, y*stride + x*cpp, stride*(h-1) + w*cpp, src) == 0;
741         } else if (drm_intel_gem_bo_map_gtt(priv->bo) == 0) {
742                 char *dst = priv->bo->virtual;
743                 int row_length = w * cpp;
744                 int num_rows = h;
745                 if (row_length == src_pitch && src_pitch == stride)
746                         num_rows = 1, row_length *= h;
747                 dst += y * stride + x * cpp;
748                 do {
749                         memcpy (dst, src, row_length);
750                         src += src_pitch;
751                         dst += stride;
752                 } while (--num_rows);
753                 drm_intel_gem_bo_unmap_gtt(priv->bo);
754                 ret = TRUE;
755         }
756
757         return ret;
758 }
759
760 static Bool intel_uxa_put_image(PixmapPtr pixmap,
761                                 int x, int y,
762                                 int w, int h,
763                                 char *src, int src_pitch)
764 {
765         struct intel_pixmap *priv;
766
767         priv = intel_get_pixmap_private(pixmap);
768         if (!intel_pixmap_is_busy(priv)) {
769                 /* bo is not busy so can be replaced without a stall, upload in-place. */
770                 return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, x, y, w, h);
771         } else {
772                 ScreenPtr screen = pixmap->drawable.pScreen;
773
774                 if (!priv->pinned &&
775                     x == 0 && y == 0 &&
776                     w == pixmap->drawable.width &&
777                     h == pixmap->drawable.height)
778                 {
779                         intel_screen_private *intel = intel_get_screen_private(xf86Screens[screen->myNum]);
780                         uint32_t tiling = priv->tiling;
781                         int size, stride;
782                         dri_bo *bo;
783
784                         /* Replace busy bo. */
785                         size = intel_uxa_pixmap_compute_size (pixmap, w, h,
786                                                               &tiling, &stride, 0);
787                         if (size > intel->max_gtt_map_size)
788                                 return FALSE;
789
790                         bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0);
791                         if (bo == NULL)
792                                 return FALSE;
793
794                         if (tiling != I915_TILING_NONE)
795                                 drm_intel_bo_set_tiling(bo, &tiling, stride);
796                         priv->stride = stride;
797                         priv->tiling = tiling;
798
799                         screen->ModifyPixmapHeader(pixmap,
800                                                    w, h,
801                                                    0, 0,
802                                                    stride, NULL);
803                         intel_set_pixmap_bo(pixmap, bo);
804                         dri_bo_unreference(bo);
805
806                         return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, 0, 0, w, h);
807                 }
808                 else
809                 {
810                         PixmapPtr scratch;
811                         Bool ret;
812
813                         /* Upload to a linear buffer and queue a blit.  */
814                         scratch = (*screen->CreatePixmap)(screen, w, h,
815                                                           pixmap->drawable.depth,
816                                                           UXA_CREATE_PIXMAP_FOR_MAP);
817                         if (!scratch)
818                                 return FALSE;
819
820                         if (!intel_uxa_pixmap_is_offscreen(scratch)) {
821                                 screen->DestroyPixmap(scratch);
822                                 return FALSE;
823                         }
824
825                         ret = intel_uxa_pixmap_put_image(scratch, src, src_pitch, 0, 0, w, h);
826                         if (ret) {
827                                 GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen);
828                                 if (gc) {
829                                         ValidateGC(&pixmap->drawable, gc);
830
831                                         (*gc->ops->CopyArea)(&scratch->drawable,
832                                                              &pixmap->drawable,
833                                                              gc, 0, 0, w, h, x, y);
834
835                                         FreeScratchGC(gc);
836                                 } else
837                                         ret = FALSE;
838                         }
839
840                         (*screen->DestroyPixmap)(scratch);
841                         return ret;
842                 }
843         }
844 }
845
846 static Bool intel_uxa_pixmap_get_image(PixmapPtr pixmap,
847                                        int x, int y, int w, int h,
848                                        char *dst, int dst_pitch)
849 {
850         struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
851         int stride = intel_pixmap_pitch(pixmap);
852         int cpp = pixmap->drawable.bitsPerPixel/8;
853
854         /* assert(priv->tiling == I915_TILING_NONE); */
855         if (h == 1 || (dst_pitch == stride && w == pixmap->drawable.width)) {
856                 return drm_intel_bo_get_subdata(priv->bo, y*stride + x*cpp, (h-1)*stride + w*cpp, dst) == 0;
857         } else {
858                 char *src;
859
860                 if (drm_intel_gem_bo_map_gtt(priv->bo))
861                     return FALSE;
862
863                 src = (char *) priv->bo->virtual + y * stride + x * cpp;
864                 w *= cpp;
865                 do {
866                         memcpy(dst, src, w);
867                         src += stride;
868                         dst += dst_pitch;
869                 } while (--h);
870
871                 drm_intel_gem_bo_unmap_gtt(priv->bo);
872
873                 return TRUE;
874         }
875 }
876
877 static Bool intel_uxa_get_image(PixmapPtr pixmap,
878                                 int x, int y,
879                                 int w, int h,
880                                 char *dst, int dst_pitch)
881 {
882         struct intel_pixmap *priv;
883         PixmapPtr scratch = NULL;
884         Bool ret;
885
886         /* The presumption is that we wish to keep the target hot, so
887          * copy to a new bo and move that to the CPU in preference to
888          * causing ping-pong of the original.
889          *
890          * Also the gpu is much faster at detiling.
891          */
892
893         priv = intel_get_pixmap_private(pixmap);
894         if (intel_pixmap_is_busy(priv) || priv->tiling != I915_TILING_NONE) {
895                 ScreenPtr screen = pixmap->drawable.pScreen;
896                 GCPtr gc;
897
898                 /* Copy to a linear buffer and pull.  */
899                 scratch = screen->CreatePixmap(screen, w, h,
900                                                pixmap->drawable.depth,
901                                                INTEL_CREATE_PIXMAP_TILING_NONE);
902                 if (!scratch)
903                         return FALSE;
904
905                 if (!intel_uxa_pixmap_is_offscreen(scratch)) {
906                         screen->DestroyPixmap(scratch);
907                         return FALSE;
908                 }
909
910                 gc = GetScratchGC(pixmap->drawable.depth, screen);
911                 if (!gc) {
912                         screen->DestroyPixmap(scratch);
913                         return FALSE;
914                 }
915
916                 ValidateGC(&pixmap->drawable, gc);
917
918                 gc->ops->CopyArea(&pixmap->drawable,
919                                   &scratch->drawable,
920                                   gc, x, y, w, h, 0, 0);
921
922                 FreeScratchGC(gc);
923
924                 intel_batch_submit(xf86Screens[screen->myNum]);
925
926                 x = y = 0;
927                 pixmap = scratch;
928         }
929
930         ret = intel_uxa_pixmap_get_image(pixmap, x, y, w, h, dst, dst_pitch);
931
932         if (scratch)
933                 scratch->drawable.pScreen->DestroyPixmap(scratch);
934
935         return ret;
936 }
937
938 static void intel_flush_rendering(intel_screen_private *intel)
939 {
940         if (intel->needs_flush == 0)
941                 return;
942
943         if (intel->has_kernel_flush) {
944                 intel_batch_submit(intel->scrn);
945                 drm_intel_bo_busy(intel->front_buffer);
946         } else {
947                 intel_batch_emit_flush(intel->scrn);
948                 intel_batch_submit(intel->scrn);
949         }
950
951         intel->needs_flush = 0;
952 }
953
954 void intel_uxa_block_handler(intel_screen_private *intel)
955 {
956         if (intel->shadow_damage &&
957             pixman_region_not_empty(DamageRegion(intel->shadow_damage))) {
958                 intel_shadow_blt(intel);
959                 DamageEmpty(intel->shadow_damage);
960         }
961
962         /* Emit a flush of the rendering cache, or on the 965
963          * and beyond rendering results may not hit the
964          * framebuffer until significantly later.
965          */
966         intel_flush_rendering(intel);
967 }
968
969 static PixmapPtr
970 intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
971                         unsigned usage)
972 {
973         ScrnInfoPtr scrn = xf86Screens[screen->myNum];
974         intel_screen_private *intel = intel_get_screen_private(scrn);
975         PixmapPtr pixmap;
976
977         if (w > 32767 || h > 32767)
978                 return NullPixmap;
979
980         if (depth == 1 || intel->force_fallback)
981                 return fbCreatePixmap(screen, w, h, depth, usage);
982
983         if (intel->use_shadow && (usage & INTEL_CREATE_PIXMAP_DRI2) == 0)
984                 return fbCreatePixmap(screen, w, h, depth, usage);
985
986         if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
987                 return fbCreatePixmap(screen, w, h, depth, usage);
988
989         pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
990
991         if (w && h) {
992                 struct intel_pixmap *priv;
993                 unsigned int size, tiling;
994                 int stride;
995
996                 /* Always attempt to tile, compute_size() will remove the
997                  * tiling for pixmaps that are either too large or too small
998                  * to be effectively tiled.
999                  */
1000                 tiling = I915_TILING_X;
1001                 if (usage & INTEL_CREATE_PIXMAP_TILING_Y)
1002                         tiling = I915_TILING_Y;
1003                 if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage & INTEL_CREATE_PIXMAP_TILING_NONE)
1004                         tiling = I915_TILING_NONE;
1005
1006                 /* if tiling is off force to none */
1007                 if (!intel->tiling)
1008                         tiling = I915_TILING_NONE;
1009
1010                 if (tiling != I915_TILING_NONE && !(usage & INTEL_CREATE_PIXMAP_DRI2)) {
1011                     if (h <= 4)
1012                         tiling = I915_TILING_NONE;
1013                     if (h <= 16 && tiling == I915_TILING_Y)
1014                         tiling = I915_TILING_X;
1015                 }
1016                 size = intel_uxa_pixmap_compute_size(pixmap, w, h, &tiling, &stride, usage);
1017
1018                 /* Fail very large allocations.  Large BOs will tend to hit SW fallbacks
1019                  * frequently, and also will tend to fail to successfully map when doing
1020                  * SW fallbacks because we overcommit address space for BO access.
1021                  */
1022                 if (size > intel->max_bo_size || stride >= KB(32)) {
1023                         fbDestroyPixmap(pixmap);
1024                         return fbCreatePixmap(screen, w, h, depth, usage);
1025                 }
1026
1027                 /* Perform a preliminary search for an in-flight bo */
1028                 if (usage != UXA_CREATE_PIXMAP_FOR_MAP) {
1029                         int aligned_h;
1030
1031                         if (tiling == I915_TILING_X)
1032                                 aligned_h = ALIGN(h, 8);
1033                         else if (tiling == I915_TILING_Y)
1034                                 aligned_h = ALIGN(h, 32);
1035                         else
1036                                 aligned_h = ALIGN(h, 2);
1037
1038                         list_foreach_entry(priv, struct intel_pixmap,
1039                                            &intel->in_flight,
1040                                            in_flight) {
1041                                 if (priv->tiling != tiling)
1042                                         continue;
1043
1044                                 if (tiling == I915_TILING_NONE) {
1045                                     if (priv->bo->size < size)
1046                                             continue;
1047
1048                                         priv->stride = stride;
1049                                 } else {
1050                                         if (priv->stride < stride ||
1051                                             priv->bo->size < priv->stride * aligned_h)
1052                                                 continue;
1053
1054                                         stride = priv->stride;
1055                                 }
1056
1057                                 list_del(&priv->in_flight);
1058                                 screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
1059                                 intel_set_pixmap_private(pixmap, priv);
1060                                 return pixmap;
1061                         }
1062                 }
1063
1064                 priv = calloc(1, sizeof (struct intel_pixmap));
1065                 if (priv == NULL) {
1066                         fbDestroyPixmap(pixmap);
1067                         return NullPixmap;
1068                 }
1069
1070                 if (usage == UXA_CREATE_PIXMAP_FOR_MAP) {
1071                         priv->busy = 0;
1072                         priv->bo = drm_intel_bo_alloc(intel->bufmgr,
1073                                                       "pixmap", size, 0);
1074                 } else {
1075                         priv->busy = -1;
1076                         priv->bo = drm_intel_bo_alloc_for_render(intel->bufmgr,
1077                                                                  "pixmap",
1078                                                                  size, 0);
1079                 }
1080                 if (!priv->bo) {
1081                         free(priv);
1082                         fbDestroyPixmap(pixmap);
1083                         return NullPixmap;
1084                 }
1085
1086                 if (tiling != I915_TILING_NONE)
1087                         drm_intel_bo_set_tiling(priv->bo, &tiling, stride);
1088                 priv->stride = stride;
1089                 priv->tiling = tiling;
1090                 priv->offscreen = 1;
1091
1092                 screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
1093
1094                 list_init(&priv->batch);
1095                 list_init(&priv->flush);
1096                 intel_set_pixmap_private(pixmap, priv);
1097         }
1098
1099         return pixmap;
1100 }
1101
1102 static Bool intel_uxa_destroy_pixmap(PixmapPtr pixmap)
1103 {
1104         if (pixmap->refcnt == 1)
1105                 intel_set_pixmap_bo(pixmap, NULL);
1106         fbDestroyPixmap(pixmap);
1107         return TRUE;
1108 }
1109
1110 Bool intel_uxa_create_screen_resources(ScreenPtr screen)
1111 {
1112         ScrnInfoPtr scrn = xf86Screens[screen->myNum];
1113         intel_screen_private *intel = intel_get_screen_private(scrn);
1114         dri_bo *bo = intel->front_buffer;
1115
1116         if (!uxa_resources_init(screen))
1117                 return FALSE;
1118
1119         drm_intel_gem_bo_map_gtt(bo);
1120
1121         if (intel->use_shadow) {
1122                 intel_shadow_create(intel);
1123         } else {
1124                 PixmapPtr pixmap = screen->GetScreenPixmap(screen);
1125                 intel_set_pixmap_bo(pixmap, bo);
1126                 intel_get_pixmap_private(pixmap)->pinned = 1;
1127                 screen->ModifyPixmapHeader(pixmap,
1128                                            scrn->virtualX,
1129                                            scrn->virtualY,
1130                                            -1, -1,
1131                                            intel->front_pitch,
1132                                            NULL);
1133                 scrn->displayWidth = intel->front_pitch / intel->cpp;
1134         }
1135
1136         return TRUE;
1137 }
1138
1139 static void
1140 intel_limits_init(intel_screen_private *intel)
1141 {
1142         /* Limits are described in the BLT engine chapter under Graphics Data Size
1143          * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO,
1144          * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO.
1145          *
1146          * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768.
1147          *
1148          * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled.
1149          * i965 limits 3D surface to 4kB-aligned offset if tiled.
1150          * i965 limits 3D surfaces to w,h of ?,8192.
1151          * i965 limits 3D surface to pitch of 1B - 128kB.
1152          * i965 limits 3D surface pitch alignment to 1 or 2 times the element size.
1153          * i965 limits 3D surface pitch alignment to 512B if tiled.
1154          * i965 limits 3D destination drawing rect to w,h of 8192,8192.
1155          *
1156          * i915 limits 3D textures to 4B-aligned offset if un-tiled.
1157          * i915 limits 3D textures to ~4kB-aligned offset if tiled.
1158          * i915 limits 3D textures to width,height of 2048,2048.
1159          * i915 limits 3D textures to pitch of 16B - 8kB, in dwords.
1160          * i915 limits 3D destination to ~4kB-aligned offset if tiled.
1161          * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled.
1162          * i915 limits 3D destination to pitch 64B-aligned if used with depth.
1163          * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled.
1164          * i915 limits 3D destination to POT aligned pitch if tiled.
1165          * i915 limits 3D destination drawing rect to w,h of 2048,2048.
1166          *
1167          * i845 limits 3D textures to 4B-aligned offset if un-tiled.
1168          * i845 limits 3D textures to ~4kB-aligned offset if tiled.
1169          * i845 limits 3D textures to width,height of 2048,2048.
1170          * i845 limits 3D textures to pitch of 4B - 8kB, in dwords.
1171          * i845 limits 3D destination to 4B-aligned offset if un-tiled.
1172          * i845 limits 3D destination to ~4kB-aligned offset if tiled.
1173          * i845 limits 3D destination to pitch of 8B - 8kB, in dwords.
1174          * i845 limits 3D destination drawing rect to w,h of 2048,2048.
1175          *
1176          * For the tiled issues, the only tiled buffer we draw to should be
1177          * the front, which will have an appropriate pitch/offset already set up,
1178          * so UXA doesn't need to worry.
1179          */
1180         if (INTEL_INFO(intel)->gen >= 40) {
1181                 intel->accel_pixmap_offset_alignment = 4 * 2;
1182                 intel->accel_max_x = 8192;
1183                 intel->accel_max_y = 8192;
1184         } else {
1185                 intel->accel_pixmap_offset_alignment = 4;
1186                 intel->accel_max_x = 2048;
1187                 intel->accel_max_y = 2048;
1188         }
1189 }
1190
1191 Bool intel_uxa_init(ScreenPtr screen)
1192 {
1193         ScrnInfoPtr scrn = xf86Screens[screen->myNum];
1194         intel_screen_private *intel = intel_get_screen_private(scrn);
1195
1196 #if HAS_DIXREGISTERPRIVATEKEY
1197         if (!dixRegisterPrivateKey(&uxa_pixmap_index, PRIVATE_PIXMAP, 0))
1198 #else
1199         if (!dixRequestPrivate(&uxa_pixmap_index, 0))
1200 #endif
1201                 return FALSE;
1202
1203         intel_limits_init(intel);
1204
1205         intel->uxa_driver = uxa_driver_alloc();
1206         if (intel->uxa_driver == NULL)
1207                 return FALSE;
1208
1209         memset(intel->uxa_driver, 0, sizeof(*intel->uxa_driver));
1210
1211         intel->uxa_driver->uxa_major = 1;
1212         intel->uxa_driver->uxa_minor = 0;
1213
1214         intel->render_current_dest = NULL;
1215         intel->prim_offset = 0;
1216         intel->vertex_count = 0;
1217         intel->vertex_offset = 0;
1218         intel->vertex_used = 0;
1219         intel->floats_per_vertex = 0;
1220         intel->last_floats_per_vertex = 0;
1221         intel->vertex_bo = NULL;
1222         intel->surface_used = 0;
1223         intel->surface_reloc = 0;
1224
1225         /* Solid fill */
1226         intel->uxa_driver->check_solid = intel_uxa_check_solid;
1227         intel->uxa_driver->prepare_solid = intel_uxa_prepare_solid;
1228         intel->uxa_driver->solid = intel_uxa_solid;
1229         intel->uxa_driver->done_solid = intel_uxa_done_solid;
1230
1231         /* Copy */
1232         intel->uxa_driver->check_copy = intel_uxa_check_copy;
1233         intel->uxa_driver->prepare_copy = intel_uxa_prepare_copy;
1234         intel->uxa_driver->copy = intel_uxa_copy;
1235         intel->uxa_driver->done_copy = intel_uxa_done_copy;
1236
1237         /* Composite */
1238         if (IS_GEN2(intel)) {
1239                 intel->uxa_driver->check_composite = i830_check_composite;
1240                 intel->uxa_driver->check_composite_target = i830_check_composite_target;
1241                 intel->uxa_driver->check_composite_texture = i830_check_composite_texture;
1242                 intel->uxa_driver->prepare_composite = i830_prepare_composite;
1243                 intel->uxa_driver->composite = i830_composite;
1244                 intel->uxa_driver->done_composite = i830_done_composite;
1245
1246                 intel->vertex_flush = i830_vertex_flush;
1247                 intel->batch_commit_notify = i830_batch_commit_notify;
1248         } else if (IS_GEN3(intel)) {
1249                 intel->uxa_driver->check_composite = i915_check_composite;
1250                 intel->uxa_driver->check_composite_target = i915_check_composite_target;
1251                 intel->uxa_driver->check_composite_texture = i915_check_composite_texture;
1252                 intel->uxa_driver->prepare_composite = i915_prepare_composite;
1253                 intel->uxa_driver->composite = i915_composite;
1254                 intel->uxa_driver->done_composite = i830_done_composite;
1255
1256                 intel->vertex_flush = i915_vertex_flush;
1257                 intel->batch_commit_notify = i915_batch_commit_notify;
1258         } else {
1259                 intel->uxa_driver->check_composite = i965_check_composite;
1260                 intel->uxa_driver->check_composite_texture = i965_check_composite_texture;
1261                 intel->uxa_driver->prepare_composite = i965_prepare_composite;
1262                 intel->uxa_driver->composite = i965_composite;
1263                 intel->uxa_driver->done_composite = i830_done_composite;
1264
1265                 intel->vertex_flush = i965_vertex_flush;
1266                 intel->batch_flush = i965_batch_flush;
1267                 intel->batch_commit_notify = i965_batch_commit_notify;
1268
1269                 if (IS_GEN4(intel)) {
1270                         intel->context_switch = gen4_context_switch;
1271                 } else if (IS_GEN5(intel)) {
1272                         intel->context_switch = gen5_context_switch;
1273                 } else {
1274                         intel->context_switch = gen6_context_switch;
1275                 }
1276         }
1277
1278         /* PutImage */
1279         intel->uxa_driver->put_image = intel_uxa_put_image;
1280         intel->uxa_driver->get_image = intel_uxa_get_image;
1281
1282         intel->uxa_driver->prepare_access = intel_uxa_prepare_access;
1283         intel->uxa_driver->pixmap_is_offscreen = intel_uxa_pixmap_is_offscreen;
1284
1285         screen->CreatePixmap = intel_uxa_create_pixmap;
1286         screen->DestroyPixmap = intel_uxa_destroy_pixmap;
1287
1288         if (!uxa_driver_init(screen, intel->uxa_driver)) {
1289                 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
1290                            "UXA initialization failed\n");
1291                 free(intel->uxa_driver);
1292                 return FALSE;
1293         }
1294
1295         uxa_set_fallback_debug(screen, intel->fallback_debug);
1296         uxa_set_force_fallback(screen, intel->force_fallback);
1297
1298         return TRUE;
1299 }