1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5 Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org>
6 Based on code from i830_xaa.c.
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:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
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.
28 **************************************************************************/
39 #include "brw_defines.h"
43 static const int I830CopyROP[16] = {
46 ROP_SDna, /* GXandReverse */
48 ROP_DSna, /* GXandInverted */
53 ROP_DSxn, /* GXequiv */
54 ROP_Dn, /* GXinvert */
55 ROP_SDno, /* GXorReverse */
56 ROP_Sn, /* GXcopyInverted */
57 ROP_DSno, /* GXorInverted */
58 ROP_DSan, /* GXnand */
62 static const int I830PatternROP[16] = {
81 #if HAS_DEVPRIVATEKEYREC
82 DevPrivateKeyRec uxa_pixmap_index;
88 gen6_context_switch(intel_screen_private *intel,
91 intel_batch_submit(intel->scrn);
95 gen5_context_switch(intel_screen_private *intel,
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.
105 if (new_mode == I915_EXEC_BLT) {
107 MI_STATE_INSTRUCTION_CACHE_FLUSH |
108 MI_INHIBIT_RENDER_CACHE_FLUSH);
110 OUT_BATCH(CMD_POLY_STIPPLE_OFFSET << 16);
116 gen4_context_switch(intel_screen_private *intel,
119 if (new_mode == I915_EXEC_BLT) {
121 MI_STATE_INSTRUCTION_CACHE_FLUSH |
122 MI_INHIBIT_RENDER_CACHE_FLUSH);
127 intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
130 intel_screen_private *intel = intel_get_screen_private(scrn);
132 if (intel->batch_bo == NULL) {
133 intel_debug_fallback(scrn, "VT inactive\n");
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) !=
143 intel_debug_fallback(scrn, "Couldn't get aperture "
152 intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
158 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
159 intel_screen_private *intel = intel_get_screen_private(scrn);
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
172 *tiling = I915_TILING_NONE;
174 /* Narrower than half a tile? */
176 *tiling = I915_TILING_NONE;
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.
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.
189 *tiling = I915_TILING_NONE;
193 pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
194 if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256)
195 *tiling = I915_TILING_NONE;
197 if (*tiling != I915_TILING_NONE) {
198 int aligned_h, tile_height;
202 else if (*tiling == I915_TILING_X)
206 aligned_h = ALIGN(h, tile_height);
208 *stride = intel_get_fence_pitch(intel,
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().
218 size = intel_get_fence_size(intel, *stride * aligned_h);
220 if (size > intel->max_tiling_size)
221 *tiling = I915_TILING_NONE;
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
229 *stride = ALIGN(pitch, 64);
230 size = *stride * ALIGN(h, 2);
237 intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
239 ScrnInfoPtr scrn = xf86Screens[drawable->pScreen->myNum];
241 if (!UXA_PM_IS_SOLID(drawable, planemask)) {
242 intel_debug_fallback(scrn, "planemask is not solid\n");
246 switch (drawable->bitsPerPixel) {
259 * Sets up hardware state for a series of solid fills.
262 intel_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
264 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
265 intel_screen_private *intel = intel_get_screen_private(scrn);
266 drm_intel_bo *bo_table[] = {
268 intel_get_pixmap_bo(pixmap),
271 if (!intel_check_pitch_2d(pixmap))
274 if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
277 intel->BR[13] = (I830PatternROP[alu] & 0xff) << 16;
278 switch (pixmap->drawable.bitsPerPixel) {
283 intel->BR[13] |= (1 << 24);
287 intel->BR[13] |= ((1 << 24) | (1 << 25));
295 static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
297 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
298 intel_screen_private *intel = intel_get_screen_private(scrn);
306 if (x2 > pixmap->drawable.width)
307 x2 = pixmap->drawable.width;
308 if (y2 > pixmap->drawable.height)
309 y2 = pixmap->drawable.height;
311 if (x2 <= x1 || y2 <= y1)
314 pitch = intel_pixmap_pitch(pixmap);
319 cmd = XY_COLOR_BLT_CMD;
321 if (pixmap->drawable.bitsPerPixel == 32)
323 XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
325 if (INTEL_INFO(intel)->gen >= 40 && intel_pixmap_tiled(pixmap)) {
326 assert((pitch % 512) == 0);
328 cmd |= XY_COLOR_BLT_TILED;
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]);
343 static void intel_uxa_done_solid(PixmapPtr pixmap)
345 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
347 intel_debug_flush(scrn);
352 * - support planemask using FULL_BLT_CMD?
355 intel_uxa_check_copy(PixmapPtr source, PixmapPtr dest,
356 int alu, Pixel planemask)
358 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
360 if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) {
361 intel_debug_fallback(scrn, "planemask is not solid");
365 if (source->drawable.bitsPerPixel != dest->drawable.bitsPerPixel) {
366 intel_debug_fallback(scrn, "mixed bpp copies unsupported\n");
369 switch (source->drawable.bitsPerPixel) {
378 if (!intel_check_pitch_2d(source))
380 if (!intel_check_pitch_2d(dest))
387 intel_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
388 int ydir, int alu, Pixel planemask)
390 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
391 intel_screen_private *intel = intel_get_screen_private(scrn);
392 drm_intel_bo *bo_table[] = {
394 intel_get_pixmap_bo(source),
395 intel_get_pixmap_bo(dest),
398 if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
401 intel->render_source = source;
403 intel->BR[13] = I830CopyROP[alu] << 16;
404 switch (source->drawable.bitsPerPixel) {
408 intel->BR[13] |= (1 << 24);
411 intel->BR[13] |= ((1 << 25) | (1 << 24));
419 intel_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
420 int dst_y1, int w, int h)
422 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
423 intel_screen_private *intel = intel_get_screen_private(scrn);
425 int dst_x2, dst_y2, src_x2, src_y2;
426 unsigned int dst_pitch, src_pitch;
431 /* XXX Fixup extents as a lamentable workaround for missing
432 * source clipping in the upper layers.
435 src_x1 -= dst_x1, dst_x1 = 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;
443 src_x2 = src_x1 + (dst_x2 - dst_x1);
444 src_y2 = src_y1 + (dst_y2 - dst_y1);
447 dst_x1 -= src_x1, src_x1 = 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;
455 if (dst_x2 <= dst_x1 || dst_y2 <= dst_y1)
458 dst_pitch = intel_pixmap_pitch(dest);
459 src_pitch = intel_pixmap_pitch(intel->render_source);
464 cmd = XY_SRC_COPY_BLT_CMD;
466 if (dest->drawable.bitsPerPixel == 32)
468 XY_SRC_COPY_BLT_WRITE_ALPHA |
469 XY_SRC_COPY_BLT_WRITE_RGB;
471 if (INTEL_INFO(intel)->gen >= 40) {
472 if (intel_pixmap_tiled(dest)) {
473 assert((dst_pitch % 512) == 0);
475 cmd |= XY_SRC_COPY_BLT_DST_TILED;
478 if (intel_pixmap_tiled(intel->render_source)) {
479 assert((src_pitch % 512) == 0);
481 cmd |= XY_SRC_COPY_BLT_SRC_TILED;
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,
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,
504 static void intel_uxa_done_copy(PixmapPtr dest)
506 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
508 intel_debug_flush(scrn);
512 * Do any cleanup from the Composite operation.
514 * This is shared between i830 through i965.
516 static void i830_done_composite(PixmapPtr dest)
518 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
519 intel_screen_private *intel = intel_get_screen_private(scrn);
521 if (intel->vertex_flush)
522 intel->vertex_flush(intel);
524 intel_debug_flush(scrn);
527 #define xFixedToFloat(val) \
528 ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
531 _intel_transform_point(PictTransformPtr transform,
532 float x, float y, float result[3])
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]));
547 * Returns the floating-point coordinates transformed by the given transform.
549 * transform may be null.
552 intel_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
553 float *x_out, float *y_out)
555 if (transform == NULL) {
561 if (!_intel_transform_point(transform,
565 *x_out = result[0] / result[2];
566 *y_out = result[1] / result[2];
572 * Returns the un-normalized floating-point coordinates transformed by the given transform.
574 * transform may be null.
577 intel_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
578 float *x_out, float *y_out, float *w_out)
580 if (transform == NULL) {
587 if (!_intel_transform_point(transform,
599 * Returns whether the provided transform is affine.
601 * transform may be null.
603 Bool intel_transform_is_affine(PictTransformPtr t)
607 return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
610 dri_bo *intel_get_pixmap_bo(PixmapPtr pixmap)
612 struct intel_pixmap *intel;
614 intel = intel_get_pixmap_private(pixmap);
621 void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
623 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
624 intel_screen_private *intel = intel_get_screen_private(scrn);
625 struct intel_pixmap *priv;
627 priv = intel_get_pixmap_private(pixmap);
629 if (priv == NULL && bo == NULL)
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);
644 list_add(&priv->in_flight, &intel->in_flight);
648 if (intel->render_current_dest == pixmap)
649 intel->render_current_dest = NULL;
654 uint32_t swizzle_mode;
658 priv = calloc(1, sizeof (struct intel_pixmap));
662 list_init(&priv->batch);
663 list_init(&priv->flush);
666 dri_bo_reference(bo);
668 priv->stride = intel_pixmap_pitch(pixmap);
670 ret = drm_intel_bo_get_tiling(bo, &tiling, &swizzle_mode);
672 FatalError("Couldn't get tiling on bo %p: %s\n",
676 priv->tiling = tiling;
687 intel_set_pixmap_private(pixmap, priv);
690 static Bool intel_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
692 struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
693 return priv && priv->offscreen;
696 static Bool intel_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
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;
704 if (!list_is_empty(&priv->batch) &&
705 (access == UXA_ACCESS_RW || priv->batch_write))
706 intel_batch_submit(scrn);
708 if (priv->tiling || bo->size <= intel->max_gtt_map_size)
709 ret = drm_intel_gem_bo_map_gtt(bo);
711 ret = dri_bo_map(bo, access == UXA_ACCESS_RW);
713 xf86DrvMsg(scrn->scrnIndex, X_WARNING,
714 "%s: bo map failed: %s\n",
720 pixmap->devPrivate.ptr = bo->virtual;
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)
730 struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
731 int stride = intel_pixmap_pitch(pixmap);
732 int cpp = pixmap->drawable.bitsPerPixel/8;
735 if (priv == NULL || priv->bo == NULL)
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;
745 if (row_length == src_pitch && src_pitch == stride)
746 num_rows = 1, row_length *= h;
747 dst += y * stride + x * cpp;
749 memcpy (dst, src, row_length);
752 } while (--num_rows);
753 drm_intel_gem_bo_unmap_gtt(priv->bo);
760 static Bool intel_uxa_put_image(PixmapPtr pixmap,
763 char *src, int src_pitch)
765 struct intel_pixmap *priv;
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);
772 ScreenPtr screen = pixmap->drawable.pScreen;
776 w == pixmap->drawable.width &&
777 h == pixmap->drawable.height)
779 intel_screen_private *intel = intel_get_screen_private(xf86Screens[screen->myNum]);
780 uint32_t tiling = priv->tiling;
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)
790 bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0);
794 if (tiling != I915_TILING_NONE)
795 drm_intel_bo_set_tiling(bo, &tiling, stride);
796 priv->stride = stride;
797 priv->tiling = tiling;
799 screen->ModifyPixmapHeader(pixmap,
803 intel_set_pixmap_bo(pixmap, bo);
804 dri_bo_unreference(bo);
806 return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, 0, 0, w, h);
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);
820 if (!intel_uxa_pixmap_is_offscreen(scratch)) {
821 screen->DestroyPixmap(scratch);
825 ret = intel_uxa_pixmap_put_image(scratch, src, src_pitch, 0, 0, w, h);
827 GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen);
829 ValidateGC(&pixmap->drawable, gc);
831 (*gc->ops->CopyArea)(&scratch->drawable,
833 gc, 0, 0, w, h, x, y);
840 (*screen->DestroyPixmap)(scratch);
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)
850 struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
851 int stride = intel_pixmap_pitch(pixmap);
852 int cpp = pixmap->drawable.bitsPerPixel/8;
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;
860 if (drm_intel_gem_bo_map_gtt(priv->bo))
863 src = (char *) priv->bo->virtual + y * stride + x * cpp;
871 drm_intel_gem_bo_unmap_gtt(priv->bo);
877 static Bool intel_uxa_get_image(PixmapPtr pixmap,
880 char *dst, int dst_pitch)
882 struct intel_pixmap *priv;
883 PixmapPtr scratch = NULL;
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.
890 * Also the gpu is much faster at detiling.
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;
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);
905 if (!intel_uxa_pixmap_is_offscreen(scratch)) {
906 screen->DestroyPixmap(scratch);
910 gc = GetScratchGC(pixmap->drawable.depth, screen);
912 screen->DestroyPixmap(scratch);
916 ValidateGC(&pixmap->drawable, gc);
918 gc->ops->CopyArea(&pixmap->drawable,
920 gc, x, y, w, h, 0, 0);
924 intel_batch_submit(xf86Screens[screen->myNum]);
930 ret = intel_uxa_pixmap_get_image(pixmap, x, y, w, h, dst, dst_pitch);
933 scratch->drawable.pScreen->DestroyPixmap(scratch);
938 static void intel_flush_rendering(intel_screen_private *intel)
940 if (intel->needs_flush == 0)
943 if (intel->has_kernel_flush) {
944 intel_batch_submit(intel->scrn);
945 drm_intel_bo_busy(intel->front_buffer);
947 intel_batch_emit_flush(intel->scrn);
948 intel_batch_submit(intel->scrn);
951 intel->needs_flush = 0;
954 void intel_uxa_block_handler(intel_screen_private *intel)
956 if (intel->shadow_damage &&
957 pixman_region_not_empty(DamageRegion(intel->shadow_damage))) {
958 intel_shadow_blt(intel);
959 DamageEmpty(intel->shadow_damage);
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.
966 intel_flush_rendering(intel);
970 intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
973 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
974 intel_screen_private *intel = intel_get_screen_private(scrn);
977 if (w > 32767 || h > 32767)
980 if (depth == 1 || intel->force_fallback)
981 return fbCreatePixmap(screen, w, h, depth, usage);
983 if (intel->use_shadow && (usage & INTEL_CREATE_PIXMAP_DRI2) == 0)
984 return fbCreatePixmap(screen, w, h, depth, usage);
986 if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
987 return fbCreatePixmap(screen, w, h, depth, usage);
989 pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
992 struct intel_pixmap *priv;
993 unsigned int size, tiling;
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.
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;
1006 /* if tiling is off force to none */
1008 tiling = I915_TILING_NONE;
1010 if (tiling != I915_TILING_NONE && !(usage & INTEL_CREATE_PIXMAP_DRI2)) {
1012 tiling = I915_TILING_NONE;
1013 if (h <= 16 && tiling == I915_TILING_Y)
1014 tiling = I915_TILING_X;
1016 size = intel_uxa_pixmap_compute_size(pixmap, w, h, &tiling, &stride, usage);
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.
1022 if (size > intel->max_bo_size || stride >= KB(32)) {
1023 fbDestroyPixmap(pixmap);
1024 return fbCreatePixmap(screen, w, h, depth, usage);
1027 /* Perform a preliminary search for an in-flight bo */
1028 if (usage != UXA_CREATE_PIXMAP_FOR_MAP) {
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);
1036 aligned_h = ALIGN(h, 2);
1038 list_foreach_entry(priv, struct intel_pixmap,
1041 if (priv->tiling != tiling)
1044 if (tiling == I915_TILING_NONE) {
1045 if (priv->bo->size < size)
1048 priv->stride = stride;
1050 if (priv->stride < stride ||
1051 priv->bo->size < priv->stride * aligned_h)
1054 stride = priv->stride;
1057 list_del(&priv->in_flight);
1058 screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
1059 intel_set_pixmap_private(pixmap, priv);
1064 priv = calloc(1, sizeof (struct intel_pixmap));
1066 fbDestroyPixmap(pixmap);
1070 if (usage == UXA_CREATE_PIXMAP_FOR_MAP) {
1072 priv->bo = drm_intel_bo_alloc(intel->bufmgr,
1076 priv->bo = drm_intel_bo_alloc_for_render(intel->bufmgr,
1082 fbDestroyPixmap(pixmap);
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;
1092 screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
1094 list_init(&priv->batch);
1095 list_init(&priv->flush);
1096 intel_set_pixmap_private(pixmap, priv);
1102 static Bool intel_uxa_destroy_pixmap(PixmapPtr pixmap)
1104 if (pixmap->refcnt == 1)
1105 intel_set_pixmap_bo(pixmap, NULL);
1106 fbDestroyPixmap(pixmap);
1110 Bool intel_uxa_create_screen_resources(ScreenPtr screen)
1112 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
1113 intel_screen_private *intel = intel_get_screen_private(scrn);
1114 dri_bo *bo = intel->front_buffer;
1116 if (!uxa_resources_init(screen))
1119 drm_intel_gem_bo_map_gtt(bo);
1121 if (intel->use_shadow) {
1122 intel_shadow_create(intel);
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,
1133 scrn->displayWidth = intel->front_pitch / intel->cpp;
1140 intel_limits_init(intel_screen_private *intel)
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.
1146 * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768.
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.
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.
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.
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.
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;
1185 intel->accel_pixmap_offset_alignment = 4;
1186 intel->accel_max_x = 2048;
1187 intel->accel_max_y = 2048;
1191 Bool intel_uxa_init(ScreenPtr screen)
1193 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
1194 intel_screen_private *intel = intel_get_screen_private(scrn);
1196 #if HAS_DIXREGISTERPRIVATEKEY
1197 if (!dixRegisterPrivateKey(&uxa_pixmap_index, PRIVATE_PIXMAP, 0))
1199 if (!dixRequestPrivate(&uxa_pixmap_index, 0))
1203 intel_limits_init(intel);
1205 intel->uxa_driver = uxa_driver_alloc();
1206 if (intel->uxa_driver == NULL)
1209 memset(intel->uxa_driver, 0, sizeof(*intel->uxa_driver));
1211 intel->uxa_driver->uxa_major = 1;
1212 intel->uxa_driver->uxa_minor = 0;
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;
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;
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;
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;
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;
1256 intel->vertex_flush = i915_vertex_flush;
1257 intel->batch_commit_notify = i915_batch_commit_notify;
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;
1265 intel->vertex_flush = i965_vertex_flush;
1266 intel->batch_flush = i965_batch_flush;
1267 intel->batch_commit_notify = i965_batch_commit_notify;
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;
1274 intel->context_switch = gen6_context_switch;
1279 intel->uxa_driver->put_image = intel_uxa_put_image;
1280 intel->uxa_driver->get_image = intel_uxa_get_image;
1282 intel->uxa_driver->prepare_access = intel_uxa_prepare_access;
1283 intel->uxa_driver->pixmap_is_offscreen = intel_uxa_pixmap_is_offscreen;
1285 screen->CreatePixmap = intel_uxa_create_pixmap;
1286 screen->DestroyPixmap = intel_uxa_destroy_pixmap;
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);
1295 uxa_set_fallback_debug(screen, intel->fallback_debug);
1296 uxa_set_force_fallback(screen, intel->force_fallback);