1d514b0f3Smrg/* 2d514b0f3Smrg * Copyright 2008 Red Hat, Inc. 3d514b0f3Smrg * 4d514b0f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5d514b0f3Smrg * copy of this software and associated documentation files (the "Software"), 6d514b0f3Smrg * to deal in the Software without restriction, including without limitation 7d514b0f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 8d514b0f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom 9d514b0f3Smrg * the Software is furnished to do so, subject to the following conditions: 10d514b0f3Smrg * 11d514b0f3Smrg * The above copyright notice and this permission notice (including the next 12d514b0f3Smrg * paragraph) shall be included in all copies or substantial portions of the 13d514b0f3Smrg * Software. 14d514b0f3Smrg * 15d514b0f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d514b0f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d514b0f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18d514b0f3Smrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19d514b0f3Smrg * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20d514b0f3Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21d514b0f3Smrg */ 22d514b0f3Smrg 23d514b0f3Smrg/** \file qxl_driver.c 24d514b0f3Smrg * \author Adam Jackson <ajax@redhat.com> 25d514b0f3Smrg * \author Søren Sandmann <sandmann@redhat.com> 26d514b0f3Smrg * 27d514b0f3Smrg * This is qxl, a driver for the Qumranet paravirtualized graphics device 28d514b0f3Smrg * in qemu. 29d514b0f3Smrg */ 30d514b0f3Smrg 31d514b0f3Smrg 32d514b0f3Smrg#ifdef HAVE_CONFIG_H 33d514b0f3Smrg#include "config.h" 34d514b0f3Smrg#endif 35d514b0f3Smrg 36d514b0f3Smrg#include "qxl.h" 37d514b0f3Smrg#include "dfps.h" 38d514b0f3Smrg#include <spice/protocol.h> 39d514b0f3Smrg 40d514b0f3Smrg#if HAS_DEVPRIVATEKEYREC 41d514b0f3SmrgDevPrivateKeyRec uxa_pixmap_index; 42d514b0f3Smrg#else 43d514b0f3Smrgint uxa_pixmap_index; 44d514b0f3Smrg#endif 45d514b0f3Smrg 46d514b0f3Smrgstatic Bool 47d514b0f3Smrgqxl_prepare_access (PixmapPtr pixmap, RegionPtr region, uxa_access_t access) 48d514b0f3Smrg{ 49d514b0f3Smrg return qxl_surface_prepare_access (get_surface (pixmap), 50d514b0f3Smrg pixmap, region, access); 51d514b0f3Smrg} 52d514b0f3Smrg 53d514b0f3Smrgstatic void 54d514b0f3Smrgqxl_finish_access (PixmapPtr pixmap) 55d514b0f3Smrg{ 56d514b0f3Smrg qxl_surface_finish_access (get_surface (pixmap), pixmap); 57d514b0f3Smrg} 58d514b0f3Smrg 59d514b0f3Smrgstatic Bool 60d514b0f3Smrgqxl_pixmap_is_offscreen (PixmapPtr pixmap) 61d514b0f3Smrg{ 62d514b0f3Smrg return !!get_surface (pixmap); 63d514b0f3Smrg} 64d514b0f3Smrg 65d514b0f3Smrgstatic Bool 66d514b0f3Smrggood_alu_and_pm (DrawablePtr drawable, int alu, Pixel planemask) 67d514b0f3Smrg{ 68d514b0f3Smrg if (!UXA_PM_IS_SOLID (drawable, planemask)) 69d514b0f3Smrg return FALSE; 70d514b0f3Smrg 71d514b0f3Smrg if (alu != GXcopy) 72d514b0f3Smrg return FALSE; 73d514b0f3Smrg 74d514b0f3Smrg return TRUE; 75d514b0f3Smrg} 76d514b0f3Smrg 77d514b0f3Smrg/* 78d514b0f3Smrg * Solid fill 79d514b0f3Smrg */ 80d514b0f3Smrgstatic Bool 81d514b0f3Smrgqxl_check_solid (DrawablePtr drawable, int alu, Pixel planemask) 82d514b0f3Smrg{ 83d514b0f3Smrg if (!good_alu_and_pm (drawable, alu, planemask)) 84d514b0f3Smrg return FALSE; 85d514b0f3Smrg 86d514b0f3Smrg return TRUE; 87d514b0f3Smrg} 88d514b0f3Smrg 89d514b0f3Smrgstatic Bool 90d514b0f3Smrgqxl_prepare_solid (PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) 91d514b0f3Smrg{ 92d514b0f3Smrg qxl_surface_t *surface; 93d514b0f3Smrg 94d514b0f3Smrg if (!(surface = get_surface (pixmap))) 95d514b0f3Smrg return FALSE; 96d514b0f3Smrg 97d514b0f3Smrg return qxl_surface_prepare_solid (surface, fg); 98d514b0f3Smrg} 99d514b0f3Smrg 100d514b0f3Smrgstatic void 101d514b0f3Smrgqxl_solid (PixmapPtr pixmap, int x1, int y1, int x2, int y2) 102d514b0f3Smrg{ 103d514b0f3Smrg qxl_surface_solid (get_surface (pixmap), x1, y1, x2, y2); 104d514b0f3Smrg} 105d514b0f3Smrg 106d514b0f3Smrgstatic void 107d514b0f3Smrgqxl_done_solid (PixmapPtr pixmap) 108d514b0f3Smrg{ 109d514b0f3Smrg} 110d514b0f3Smrg 111d514b0f3Smrg/* 112d514b0f3Smrg * Copy 113d514b0f3Smrg */ 114d514b0f3Smrgstatic Bool 115d514b0f3Smrgqxl_check_copy (PixmapPtr source, PixmapPtr dest, 116d514b0f3Smrg int alu, Pixel planemask) 117d514b0f3Smrg{ 118d514b0f3Smrg if (!good_alu_and_pm ((DrawablePtr)source, alu, planemask)) 119d514b0f3Smrg return FALSE; 120d514b0f3Smrg 121d514b0f3Smrg if (source->drawable.bitsPerPixel != dest->drawable.bitsPerPixel) 122d514b0f3Smrg { 123d514b0f3Smrg ErrorF ("differing bitsperpixel - this shouldn't happen\n"); 124d514b0f3Smrg return FALSE; 125d514b0f3Smrg } 126d514b0f3Smrg 127d514b0f3Smrg return TRUE; 128d514b0f3Smrg} 129d514b0f3Smrg 130d514b0f3Smrgstatic Bool 131d514b0f3Smrgqxl_prepare_copy (PixmapPtr source, PixmapPtr dest, 132d514b0f3Smrg int xdir, int ydir, int alu, 133d514b0f3Smrg Pixel planemask) 134d514b0f3Smrg{ 135d514b0f3Smrg return qxl_surface_prepare_copy (get_surface (dest), get_surface (source)); 136d514b0f3Smrg} 137d514b0f3Smrg 138d514b0f3Smrgstatic void 139d514b0f3Smrgqxl_copy (PixmapPtr dest, 140d514b0f3Smrg int src_x1, int src_y1, 141d514b0f3Smrg int dest_x1, int dest_y1, 142d514b0f3Smrg int width, int height) 143d514b0f3Smrg{ 144d514b0f3Smrg qxl_surface_copy (get_surface (dest), 145d514b0f3Smrg src_x1, src_y1, 146d514b0f3Smrg dest_x1, dest_y1, 147d514b0f3Smrg width, height); 148d514b0f3Smrg} 149d514b0f3Smrg 150d514b0f3Smrgstatic void 151d514b0f3Smrgqxl_done_copy (PixmapPtr dest) 152d514b0f3Smrg{ 153d514b0f3Smrg} 154d514b0f3Smrg 155d514b0f3Smrg/* 156d514b0f3Smrg * Composite 157d514b0f3Smrg */ 158d514b0f3Smrgstatic Bool 159d514b0f3Smrgcan_accelerate_picture (qxl_screen_t *qxl, PicturePtr pict) 160d514b0f3Smrg{ 161d514b0f3Smrg if (!pict) 162d514b0f3Smrg return TRUE; 163d514b0f3Smrg 164d514b0f3Smrg if (pict->format != PICT_a8r8g8b8 && 165d514b0f3Smrg pict->format != PICT_x8r8g8b8 && 166d514b0f3Smrg pict->format != PICT_a8) 167d514b0f3Smrg { 168d514b0f3Smrg if (qxl->debug_render_fallbacks) 169d514b0f3Smrg { 170d514b0f3Smrg ErrorF ("Image with format %x can't be accelerated \n", 171d514b0f3Smrg pict->format); 172d514b0f3Smrg } 173d514b0f3Smrg 174d514b0f3Smrg return FALSE; 175d514b0f3Smrg } 176d514b0f3Smrg 177d514b0f3Smrg if (!pict->pDrawable) 178d514b0f3Smrg { 179d514b0f3Smrg if (qxl->debug_render_fallbacks) 180d514b0f3Smrg { 181d514b0f3Smrg ErrorF ("Source image (of type %d) can't be accelerated\n", 182d514b0f3Smrg pict->pSourcePict->type); 183d514b0f3Smrg } 184d514b0f3Smrg 185d514b0f3Smrg return FALSE; 186d514b0f3Smrg } 187d514b0f3Smrg 188d514b0f3Smrg if (pict->transform) 189d514b0f3Smrg { 190d514b0f3Smrg if (pict->transform->matrix[2][0] != 0 || 191d514b0f3Smrg pict->transform->matrix[2][1] != 0 || 192d514b0f3Smrg pict->transform->matrix[2][2] != pixman_int_to_fixed (1)) 193d514b0f3Smrg { 194d514b0f3Smrg if (qxl->debug_render_fallbacks) 195d514b0f3Smrg ErrorF ("Image with non-affine transform can't be accelerated\n"); 196d514b0f3Smrg 197d514b0f3Smrg return FALSE; 198d514b0f3Smrg } 199d514b0f3Smrg } 200d514b0f3Smrg 201d514b0f3Smrg if (pict->filter != PictFilterBilinear && 202d514b0f3Smrg pict->filter != PictFilterNearest) 203d514b0f3Smrg { 204d514b0f3Smrg if (qxl->debug_render_fallbacks) 205d514b0f3Smrg { 206d514b0f3Smrg ErrorF ("Image with filter type %d can't be accelerated\n", 207d514b0f3Smrg pict->filter); 208d514b0f3Smrg } 209d514b0f3Smrg 210d514b0f3Smrg return FALSE; 211d514b0f3Smrg } 212d514b0f3Smrg 213d514b0f3Smrg return TRUE; 214d514b0f3Smrg} 215d514b0f3Smrg 216d514b0f3Smrg#define QXL_HAS_CAP(qxl, cap) \ 217d514b0f3Smrg (((qxl)->rom->client_capabilities[(cap) / 8]) & (1 << ((cap) % 8))) 218d514b0f3Smrg 219d514b0f3Smrgstatic Bool 220d514b0f3Smrgqxl_has_composite (qxl_screen_t *qxl) 221d514b0f3Smrg{ 222d514b0f3Smrg#ifdef XF86DRM_MODE 223d514b0f3Smrg if (qxl->kms_enabled) { 224d514b0f3Smrg#if 0 /* KMS Composite support seems broken - needs better hw support */ 225d514b0f3Smrg static Bool result, checked; 226d514b0f3Smrg if (!checked) { 227d514b0f3Smrg result = qxl_kms_check_cap(qxl, SPICE_DISPLAY_CAP_COMPOSITE); 228d514b0f3Smrg checked = TRUE; 229d514b0f3Smrg } 230d514b0f3Smrg return result; 231d514b0f3Smrg#else 232d514b0f3Smrg return FALSE; 233d514b0f3Smrg#endif 234d514b0f3Smrg } 235d514b0f3Smrg#endif 236d514b0f3Smrg#ifndef XSPICE 237d514b0f3Smrg return 238d514b0f3Smrg qxl->pci->revision >= 4 && 239d514b0f3Smrg QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE); 240d514b0f3Smrg#else 241d514b0f3Smrg /* FIXME */ 242d514b0f3Smrg return FALSE; 243d514b0f3Smrg#endif 244d514b0f3Smrg} 245d514b0f3Smrg 246d514b0f3Smrgstatic Bool 247d514b0f3Smrgqxl_has_a8_surfaces (qxl_screen_t *qxl) 248d514b0f3Smrg{ 249d514b0f3Smrg#ifdef XF86DRM_MODE 250d514b0f3Smrg if (qxl->kms_enabled) { 251d514b0f3Smrg#if 0 /* KMS Composite support seems broken - needs better hw support */ 252d514b0f3Smrg static Bool result, checked; 253d514b0f3Smrg if (!checked) { 254d514b0f3Smrg result = qxl_kms_check_cap(qxl, SPICE_DISPLAY_CAP_A8_SURFACE); 255d514b0f3Smrg checked = TRUE; 256d514b0f3Smrg } 257d514b0f3Smrg return result; 258d514b0f3Smrg#else 259d514b0f3Smrg return FALSE; 260d514b0f3Smrg#endif 261d514b0f3Smrg } 262d514b0f3Smrg#endif 263d514b0f3Smrg#ifndef XSPICE 264d514b0f3Smrg if (qxl->pci->revision < 4) 265d514b0f3Smrg { 266d514b0f3Smrg if (qxl->debug_render_fallbacks) 267d514b0f3Smrg { 268d514b0f3Smrg ErrorF ("No a8 surface due to revision being %d, which is < 4\n", 269d514b0f3Smrg qxl->pci->revision); 270d514b0f3Smrg } 271d514b0f3Smrg 272d514b0f3Smrg return FALSE; 273d514b0f3Smrg } 274d514b0f3Smrg 275d514b0f3Smrg if (!QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE)) 276d514b0f3Smrg { 277d514b0f3Smrg if (qxl->debug_render_fallbacks) 278d514b0f3Smrg { 279d514b0f3Smrg ErrorF ("No composite due to client not providing SPICE_DISPLAY_CAP_A8_SURFACE\n"); 280d514b0f3Smrg } 281d514b0f3Smrg 282d514b0f3Smrg return FALSE; 283d514b0f3Smrg } 284d514b0f3Smrg 285d514b0f3Smrg return TRUE; 286d514b0f3Smrg 287d514b0f3Smrg#else 288d514b0f3Smrg /* FIXME */ 289d514b0f3Smrg return FALSE; 290d514b0f3Smrg#endif 291d514b0f3Smrg} 292d514b0f3Smrg 293d514b0f3Smrgstatic Bool 294d514b0f3Smrgqxl_check_composite (int op, 295d514b0f3Smrg PicturePtr pSrcPicture, 296d514b0f3Smrg PicturePtr pMaskPicture, 297d514b0f3Smrg PicturePtr pDstPicture, 298d514b0f3Smrg int width, int height) 299d514b0f3Smrg{ 300d514b0f3Smrg int i; 301d514b0f3Smrg ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; 302d514b0f3Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); 303d514b0f3Smrg qxl_screen_t *qxl = pScrn->driverPrivate; 304d514b0f3Smrg 305d514b0f3Smrg static const int accelerated_ops[] = 306d514b0f3Smrg { 307d514b0f3Smrg PictOpClear, PictOpSrc, PictOpDst, PictOpOver, PictOpOverReverse, 308d514b0f3Smrg PictOpIn, PictOpInReverse, PictOpOut, PictOpOutReverse, 309d514b0f3Smrg PictOpAtop, PictOpAtopReverse, PictOpXor, PictOpAdd, 310d514b0f3Smrg PictOpSaturate, PictOpMultiply, PictOpScreen, PictOpOverlay, 311d514b0f3Smrg PictOpDarken, PictOpLighten, PictOpColorDodge, PictOpColorBurn, 312d514b0f3Smrg PictOpHardLight, PictOpSoftLight, PictOpDifference, PictOpExclusion, 313d514b0f3Smrg PictOpHSLHue, PictOpHSLSaturation, PictOpHSLColor, PictOpHSLLuminosity, 314d514b0f3Smrg }; 315d514b0f3Smrg 316d514b0f3Smrg if (!qxl_has_composite (qxl)) 317d514b0f3Smrg return FALSE; 318d514b0f3Smrg 319d514b0f3Smrg if (!can_accelerate_picture (qxl, pSrcPicture) || 320d514b0f3Smrg !can_accelerate_picture (qxl, pMaskPicture) || 321d514b0f3Smrg !can_accelerate_picture (qxl, pDstPicture)) 322d514b0f3Smrg { 323d514b0f3Smrg return FALSE; 324d514b0f3Smrg } 325d514b0f3Smrg 326d514b0f3Smrg for (i = 0; i < sizeof (accelerated_ops) / sizeof (accelerated_ops[0]); ++i) 327d514b0f3Smrg { 328d514b0f3Smrg if (accelerated_ops[i] == op) 329d514b0f3Smrg goto found; 330d514b0f3Smrg } 331d514b0f3Smrg 332d514b0f3Smrg if (qxl->debug_render_fallbacks) 333d514b0f3Smrg ErrorF ("Compositing operator %d can't be accelerated\n", op); 334d514b0f3Smrg 335d514b0f3Smrg return FALSE; 336d514b0f3Smrg 337d514b0f3Smrgfound: 338d514b0f3Smrg return TRUE; 339d514b0f3Smrg} 340d514b0f3Smrg 341d514b0f3Smrgstatic Bool 342d514b0f3Smrgqxl_check_composite_target (PixmapPtr pixmap) 343d514b0f3Smrg{ 344d514b0f3Smrg return TRUE; 345d514b0f3Smrg} 346d514b0f3Smrg 347d514b0f3Smrgstatic Bool 348d514b0f3Smrgqxl_check_composite_texture (ScreenPtr screen, 349d514b0f3Smrg PicturePtr pPicture) 350d514b0f3Smrg{ 351d514b0f3Smrg return TRUE; 352d514b0f3Smrg} 353d514b0f3Smrg 354d514b0f3Smrgstatic Bool 355d514b0f3Smrgqxl_prepare_composite (int op, 356d514b0f3Smrg PicturePtr pSrcPicture, 357d514b0f3Smrg PicturePtr pMaskPicture, 358d514b0f3Smrg PicturePtr pDstPicture, 359d514b0f3Smrg PixmapPtr pSrc, 360d514b0f3Smrg PixmapPtr pMask, 361d514b0f3Smrg PixmapPtr pDst) 362d514b0f3Smrg{ 363d514b0f3Smrg return qxl_surface_prepare_composite ( 364d514b0f3Smrg op, pSrcPicture, pMaskPicture, pDstPicture, 365d514b0f3Smrg get_surface (pSrc), 366d514b0f3Smrg pMask? get_surface (pMask) : NULL, 367d514b0f3Smrg get_surface (pDst)); 368d514b0f3Smrg} 369d514b0f3Smrg 370d514b0f3Smrgstatic void 371d514b0f3Smrgqxl_composite (PixmapPtr pDst, 372d514b0f3Smrg int src_x, int src_y, 373d514b0f3Smrg int mask_x, int mask_y, 374d514b0f3Smrg int dst_x, int dst_y, 375d514b0f3Smrg int width, int height) 376d514b0f3Smrg{ 377d514b0f3Smrg qxl_surface_composite ( 378d514b0f3Smrg get_surface (pDst), 379d514b0f3Smrg src_x, src_y, 380d514b0f3Smrg mask_x, mask_y, 381d514b0f3Smrg dst_x, dst_y, width, height); 382d514b0f3Smrg} 383d514b0f3Smrg 384d514b0f3Smrgstatic void 385d514b0f3Smrgqxl_done_composite (PixmapPtr pDst) 386d514b0f3Smrg{ 387d514b0f3Smrg ; 388d514b0f3Smrg} 389d514b0f3Smrg 390d514b0f3Smrgstatic Bool 391d514b0f3Smrgqxl_put_image (PixmapPtr pDst, int x, int y, int w, int h, 392d514b0f3Smrg char *src, int src_pitch) 393d514b0f3Smrg{ 394d514b0f3Smrg qxl_surface_t *surface = get_surface (pDst); 395d514b0f3Smrg 396d514b0f3Smrg if (surface) 397d514b0f3Smrg return qxl_surface_put_image (surface, x, y, w, h, src, src_pitch); 398d514b0f3Smrg 399d514b0f3Smrg return FALSE; 400d514b0f3Smrg} 401d514b0f3Smrg 402d514b0f3Smrgstatic void 403d514b0f3Smrgqxl_set_screen_pixmap (PixmapPtr pixmap) 404d514b0f3Smrg{ 405d514b0f3Smrg pixmap->drawable.pScreen->devPrivate = pixmap; 406d514b0f3Smrg} 407d514b0f3Smrg 408d514b0f3Smrgstatic PixmapPtr 409d514b0f3Smrgqxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage) 410d514b0f3Smrg{ 411d514b0f3Smrg ScrnInfoPtr scrn = xf86ScreenToScrn (screen); 412d514b0f3Smrg PixmapPtr pixmap; 413d514b0f3Smrg qxl_screen_t * qxl = scrn->driverPrivate; 414d514b0f3Smrg qxl_surface_t *surface; 415d514b0f3Smrg 416d514b0f3Smrg if (w > 32767 || h > 32767) 417d514b0f3Smrg return NULL; 418d514b0f3Smrg 419d514b0f3Smrg qxl_surface_cache_sanity_check (qxl->surface_cache); 420d514b0f3Smrg 421d514b0f3Smrg#if 0 422d514b0f3Smrg ErrorF ("Create pixmap: %d %d @ %d (usage: %d)\n", w, h, depth, usage); 423d514b0f3Smrg#endif 424d514b0f3Smrg 425d514b0f3Smrg if (qxl->kms_enabled) 426d514b0f3Smrg goto fallback; 427d514b0f3Smrg if (uxa_swapped_out (screen)) 428d514b0f3Smrg goto fallback; 429d514b0f3Smrg 430d514b0f3Smrg if (depth == 8 && !qxl_has_a8_surfaces (qxl)) 431d514b0f3Smrg { 432d514b0f3Smrg /* FIXME: When we detect a _change_ in the property of having a8 433d514b0f3Smrg * surfaces, we should copy all existing a8 surface to host memory 434d514b0f3Smrg * and then destroy the ones on the device. 435d514b0f3Smrg */ 436d514b0f3Smrg goto fallback; 437d514b0f3Smrg } 438d514b0f3Smrg 439d514b0f3Smrg if (!w || !h) 440d514b0f3Smrg goto fallback; 441d514b0f3Smrg 442d514b0f3Smrg surface = qxl->bo_funcs->create_surface (qxl, w, h, depth); 443d514b0f3Smrg if (surface) 444d514b0f3Smrg { 445d514b0f3Smrg /* ErrorF (" Successfully created surface in video memory\n"); */ 446d514b0f3Smrg 447d514b0f3Smrg pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); 448d514b0f3Smrg 449d514b0f3Smrg screen->ModifyPixmapHeader (pixmap, w, h, 450d514b0f3Smrg -1, -1, -1, 451d514b0f3Smrg NULL); 452d514b0f3Smrg 453d514b0f3Smrg#if 0 454d514b0f3Smrg ErrorF ("Create pixmap %p with surface %p\n", pixmap, surface); 455d514b0f3Smrg#endif 456d514b0f3Smrg set_surface (pixmap, surface); 457d514b0f3Smrg qxl_surface_set_pixmap (surface, pixmap); 458d514b0f3Smrg 459d514b0f3Smrg qxl_surface_cache_sanity_check (qxl->surface_cache); 460d514b0f3Smrg } 461d514b0f3Smrg else 462d514b0f3Smrg { 463d514b0f3Smrg#if 0 464d514b0f3Smrg ErrorF (" Couldn't allocate %d x %d @ %d surface in video memory\n", 465d514b0f3Smrg w, h, depth); 466d514b0f3Smrg#endif 467d514b0f3Smrg fallback: 468d514b0f3Smrg pixmap = fbCreatePixmap (screen, w, h, depth, usage); 469d514b0f3Smrg 470d514b0f3Smrg#if 0 471d514b0f3Smrg ErrorF ("Create pixmap %p without surface\n", pixmap); 472d514b0f3Smrg#endif 473d514b0f3Smrg } 474d514b0f3Smrg 475d514b0f3Smrg return pixmap; 476d514b0f3Smrg} 477d514b0f3Smrg 478d514b0f3Smrgstatic Bool 479d514b0f3Smrgqxl_destroy_pixmap (PixmapPtr pixmap) 480d514b0f3Smrg{ 481d514b0f3Smrg ScreenPtr screen = pixmap->drawable.pScreen; 482d514b0f3Smrg ScrnInfoPtr scrn = xf86ScreenToScrn (screen); 483d514b0f3Smrg qxl_screen_t * qxl = scrn->driverPrivate; 484d514b0f3Smrg qxl_surface_t *surface = NULL; 485d514b0f3Smrg 486d514b0f3Smrg qxl_surface_cache_sanity_check (qxl->surface_cache); 487d514b0f3Smrg 488d514b0f3Smrg if (pixmap->refcnt == 1) 489d514b0f3Smrg { 490d514b0f3Smrg surface = get_surface (pixmap); 491d514b0f3Smrg 492d514b0f3Smrg#if 0 493d514b0f3Smrg ErrorF ("- Destroy %p (had surface %p)\n", pixmap, surface); 494d514b0f3Smrg#endif 495d514b0f3Smrg 496d514b0f3Smrg if (surface) 497d514b0f3Smrg { 498d514b0f3Smrg qxl->bo_funcs->destroy_surface(surface); 499d514b0f3Smrg set_surface (pixmap, NULL); 500d514b0f3Smrg 501d514b0f3Smrg qxl_surface_cache_sanity_check (qxl->surface_cache); 502d514b0f3Smrg } 503d514b0f3Smrg } 504d514b0f3Smrg 505d514b0f3Smrg fbDestroyPixmap (pixmap); 506d514b0f3Smrg return TRUE; 507d514b0f3Smrg} 508d514b0f3Smrg 509d514b0f3Smrgstatic void 510d514b0f3Smrgset_uxa_functions(qxl_screen_t *qxl, ScreenPtr screen) 511d514b0f3Smrg{ 512d514b0f3Smrg /* Solid fill */ 513d514b0f3Smrg qxl->uxa->check_solid = qxl_check_solid; 514d514b0f3Smrg qxl->uxa->prepare_solid = qxl_prepare_solid; 515d514b0f3Smrg qxl->uxa->solid = qxl_solid; 516d514b0f3Smrg qxl->uxa->done_solid = qxl_done_solid; 517d514b0f3Smrg 518d514b0f3Smrg /* Copy */ 519d514b0f3Smrg qxl->uxa->check_copy = qxl_check_copy; 520d514b0f3Smrg qxl->uxa->prepare_copy = qxl_prepare_copy; 521d514b0f3Smrg qxl->uxa->copy = qxl_copy; 522d514b0f3Smrg qxl->uxa->done_copy = qxl_done_copy; 523d514b0f3Smrg 524d514b0f3Smrg /* Composite */ 525d514b0f3Smrg qxl->uxa->check_composite = qxl_check_composite; 526d514b0f3Smrg qxl->uxa->check_composite_target = qxl_check_composite_target; 527d514b0f3Smrg qxl->uxa->check_composite_texture = qxl_check_composite_texture; 528d514b0f3Smrg qxl->uxa->prepare_composite = qxl_prepare_composite; 529d514b0f3Smrg qxl->uxa->composite = qxl_composite; 530d514b0f3Smrg qxl->uxa->done_composite = qxl_done_composite; 531d514b0f3Smrg 532d514b0f3Smrg /* PutImage */ 533d514b0f3Smrg qxl->uxa->put_image = qxl_put_image; 534d514b0f3Smrg 535d514b0f3Smrg /* Prepare access */ 536d514b0f3Smrg qxl->uxa->prepare_access = qxl_prepare_access; 537d514b0f3Smrg qxl->uxa->finish_access = qxl_finish_access; 538d514b0f3Smrg 539d514b0f3Smrg qxl->uxa->pixmap_is_offscreen = qxl_pixmap_is_offscreen; 540d514b0f3Smrg 541d514b0f3Smrg screen->SetScreenPixmap = qxl_set_screen_pixmap; 542d514b0f3Smrg screen->CreatePixmap = qxl_create_pixmap; 543d514b0f3Smrg screen->DestroyPixmap = qxl_destroy_pixmap; 544d514b0f3Smrg} 545d514b0f3Smrg 546d514b0f3SmrgBool 547d514b0f3Smrgqxl_uxa_init (qxl_screen_t *qxl, ScreenPtr screen) 548d514b0f3Smrg{ 549d514b0f3Smrg ScrnInfoPtr scrn = xf86ScreenToScrn (screen); 550d514b0f3Smrg 551d514b0f3Smrg#if HAS_DIXREGISTERPRIVATEKEY 552d514b0f3Smrg if (!dixRegisterPrivateKey (&uxa_pixmap_index, PRIVATE_PIXMAP, 0)) 553d514b0f3Smrg return FALSE; 554d514b0f3Smrg#else 555d514b0f3Smrg if (!dixRequestPrivate (&uxa_pixmap_index, 0)) 556d514b0f3Smrg return FALSE; 557d514b0f3Smrg#endif 558d514b0f3Smrg 559d514b0f3Smrg qxl->uxa = uxa_driver_alloc (); 560d514b0f3Smrg if (qxl->uxa == NULL) 561d514b0f3Smrg return FALSE; 562d514b0f3Smrg 563d514b0f3Smrg memset (qxl->uxa, 0, sizeof (*qxl->uxa)); 564d514b0f3Smrg 565d514b0f3Smrg qxl->uxa->uxa_major = 1; 566d514b0f3Smrg qxl->uxa->uxa_minor = 0; 567d514b0f3Smrg 568d514b0f3Smrg if (qxl->deferred_fps) 569d514b0f3Smrg dfps_set_uxa_functions(qxl, screen); 570d514b0f3Smrg else 571d514b0f3Smrg set_uxa_functions(qxl, screen); 572d514b0f3Smrg 573d514b0f3Smrg if (!uxa_driver_init (screen, qxl->uxa)) 574d514b0f3Smrg { 575d514b0f3Smrg xf86DrvMsg (scrn->scrnIndex, X_ERROR, 576d514b0f3Smrg "UXA initialization failed\n"); 577d514b0f3Smrg free (qxl->uxa); 578d514b0f3Smrg return FALSE; 579d514b0f3Smrg } 580d514b0f3Smrg 581d514b0f3Smrg#if 0 582d514b0f3Smrg uxa_set_fallback_debug (screen, FALSE); 583d514b0f3Smrg#endif 584d514b0f3Smrg 585d514b0f3Smrg#if 0 586d514b0f3Smrg if (!uxa_driver_init (screen, qxl->uxa)) 587d514b0f3Smrg return FALSE; 588d514b0f3Smrg#endif 589d514b0f3Smrg 590d514b0f3Smrg return TRUE; 591d514b0f3Smrg} 592