1fda9279dSmrg/* 2fda9279dSmrg * Copyright 2009 Nouveau Project 3fda9279dSmrg * 4fda9279dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5fda9279dSmrg * copy of this software and associated documentation files (the "Software"), 6fda9279dSmrg * to deal in the Software without restriction, including without limitation 7fda9279dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8fda9279dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9fda9279dSmrg * Software is furnished to do so, subject to the following conditions: 10fda9279dSmrg * 11fda9279dSmrg * The above copyright notice and this permission notice shall be included in 12fda9279dSmrg * all copies or substantial portions of the Software. 13fda9279dSmrg * 14fda9279dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15fda9279dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16fda9279dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17fda9279dSmrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18fda9279dSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19fda9279dSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20fda9279dSmrg * SOFTWARE. 21fda9279dSmrg */ 22fda9279dSmrg 23fda9279dSmrg#include "nv_include.h" 24fda9279dSmrg#include "exa.h" 25fda9279dSmrg 26fda9279dSmrg#include "hwdefs/nv_m2mf.xml.h" 27fda9279dSmrg 28fda9279dSmrgstatic inline Bool 29fda9279dSmrgNVAccelMemcpyRect(char *dst, const char *src, int height, int dst_pitch, 30fda9279dSmrg int src_pitch, int line_len) 31fda9279dSmrg{ 32fda9279dSmrg if ((src_pitch == line_len) && (src_pitch == dst_pitch)) { 33fda9279dSmrg memcpy(dst, src, line_len*height); 34fda9279dSmrg } else { 35fda9279dSmrg while (height--) { 36fda9279dSmrg memcpy(dst, src, line_len); 37fda9279dSmrg src += src_pitch; 38fda9279dSmrg dst += dst_pitch; 39fda9279dSmrg } 40fda9279dSmrg } 41fda9279dSmrg 42fda9279dSmrg return TRUE; 43fda9279dSmrg} 44fda9279dSmrg 45fda9279dSmrgBool 46fda9279dSmrgNVAccelM2MF(NVPtr pNv, int w, int h, int cpp, uint32_t srcoff, uint32_t dstoff, 47fda9279dSmrg struct nouveau_bo *src, int sd, int sp, int sh, int sx, int sy, 48fda9279dSmrg struct nouveau_bo *dst, int dd, int dp, int dh, int dx, int dy) 49fda9279dSmrg{ 50fda9279dSmrg if (pNv->ce_rect && pNv->ce_enabled) 51fda9279dSmrg return pNv->ce_rect(pNv->ce_pushbuf, pNv->NvCopy, w, h, cpp, 52fda9279dSmrg src, srcoff, sd, sp, sh, sx, sy, 53fda9279dSmrg dst, dstoff, dd, dp, dh, dx, dy); 54fda9279dSmrg else 55fda9279dSmrg if (pNv->Architecture >= NV_KEPLER) 56fda9279dSmrg return NVE0EXARectCopy(pNv, w, h, cpp, 57fda9279dSmrg src, srcoff, sd, sp, sh, sx, sy, 58fda9279dSmrg dst, dstoff, dd, dp, dh, dx, dy); 59fda9279dSmrg else 60fda9279dSmrg if (pNv->Architecture >= NV_FERMI) 61fda9279dSmrg return NVC0EXARectM2MF(pNv, w, h, cpp, 62fda9279dSmrg src, srcoff, sd, sp, sh, sx, sy, 63fda9279dSmrg dst, dstoff, dd, dp, dh, dx, dy); 64fda9279dSmrg else 65fda9279dSmrg if (pNv->Architecture >= NV_TESLA) 66fda9279dSmrg return NV50EXARectM2MF(pNv, w, h, cpp, 67fda9279dSmrg src, srcoff, sd, sp, sh, sx, sy, 68fda9279dSmrg dst, dstoff, dd, dp, dh, dx, dy); 69fda9279dSmrg else 70fda9279dSmrg return NV04EXARectM2MF(pNv, w, h, cpp, 71fda9279dSmrg src, srcoff, sd, sp, sh, sx, sy, 72fda9279dSmrg dst, dstoff, dd, dp, dh, dx, dy); 73fda9279dSmrg return FALSE; 74fda9279dSmrg} 75fda9279dSmrg 76fda9279dSmrgstatic int 77fda9279dSmrgnouveau_exa_mark_sync(ScreenPtr pScreen) 78fda9279dSmrg{ 79fda9279dSmrg return 0; 80fda9279dSmrg} 81fda9279dSmrg 82fda9279dSmrgstatic void 83fda9279dSmrgnouveau_exa_wait_marker(ScreenPtr pScreen, int marker) 84fda9279dSmrg{ 85fda9279dSmrg} 86fda9279dSmrg 87fda9279dSmrgstatic Bool 88fda9279dSmrgnouveau_exa_prepare_access(PixmapPtr ppix, int index) 89fda9279dSmrg{ 90fda9279dSmrg struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); 91fda9279dSmrg NVPtr pNv = NVPTR(xf86ScreenToScrn(ppix->drawable.pScreen)); 92fda9279dSmrg 93fda9279dSmrg if (nv50_style_tiled_pixmap(ppix) && !pNv->wfb_enabled) 94fda9279dSmrg return FALSE; 95fda9279dSmrg if (nouveau_bo_map(bo, NOUVEAU_BO_RDWR, pNv->client)) 96fda9279dSmrg return FALSE; 97fda9279dSmrg ppix->devPrivate.ptr = bo->map; 98fda9279dSmrg return TRUE; 99fda9279dSmrg} 100fda9279dSmrg 101fda9279dSmrgstatic void 102fda9279dSmrgnouveau_exa_finish_access(PixmapPtr ppix, int index) 103fda9279dSmrg{ 104fda9279dSmrg} 105fda9279dSmrg 106fda9279dSmrgstatic Bool 107fda9279dSmrgnouveau_exa_pixmap_is_offscreen(PixmapPtr ppix) 108fda9279dSmrg{ 109fda9279dSmrg return nouveau_pixmap_bo(ppix) != NULL; 110fda9279dSmrg} 111fda9279dSmrg 112fda9279dSmrgstatic void * 113fda9279dSmrgnouveau_exa_create_pixmap(ScreenPtr pScreen, int width, int height, int depth, 114fda9279dSmrg int usage_hint, int bitsPerPixel, int *new_pitch) 115fda9279dSmrg{ 116fda9279dSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); 117fda9279dSmrg NVPtr pNv = NVPTR(scrn); 118fda9279dSmrg struct nouveau_pixmap *nvpix; 119fda9279dSmrg int ret; 120fda9279dSmrg 121fda9279dSmrg if (!width || !height) 122fda9279dSmrg return calloc(1, sizeof(*nvpix)); 123fda9279dSmrg 124fda9279dSmrg if (!pNv->exa_force_cp && pNv->dev->vram_size <= 32 * 1024 * 1024) 125fda9279dSmrg return NULL; 126fda9279dSmrg 127fda9279dSmrg nvpix = calloc(1, sizeof(*nvpix)); 128fda9279dSmrg if (!nvpix) 129fda9279dSmrg return NULL; 130fda9279dSmrg 131fda9279dSmrg ret = nouveau_allocate_surface(scrn, width, height, bitsPerPixel, 132fda9279dSmrg usage_hint, new_pitch, &nvpix->bo); 133fda9279dSmrg if (!ret) { 134fda9279dSmrg free(nvpix); 135fda9279dSmrg return NULL; 136fda9279dSmrg } 137fda9279dSmrg 138fda9279dSmrg#ifdef NOUVEAU_PIXMAP_SHARING 139fda9279dSmrg if ((usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) 140fda9279dSmrg nvpix->shared = TRUE; 141fda9279dSmrg#endif 142fda9279dSmrg 143fda9279dSmrg return nvpix; 144fda9279dSmrg} 145fda9279dSmrg 146fda9279dSmrgstatic void 147fda9279dSmrgnouveau_exa_destroy_pixmap(ScreenPtr pScreen, void *priv) 148fda9279dSmrg{ 149fda9279dSmrg struct nouveau_pixmap *nvpix = priv; 150fda9279dSmrg 151fda9279dSmrg if (!nvpix) 152fda9279dSmrg return; 153fda9279dSmrg 154fda9279dSmrg nouveau_bo_ref(NULL, &nvpix->bo); 155fda9279dSmrg free(nvpix); 156fda9279dSmrg} 157fda9279dSmrg 158fda9279dSmrg#ifdef NOUVEAU_PIXMAP_SHARING 159fda9279dSmrgstatic Bool 16033adc6acSmrgnouveau_exa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr secondary, void **handle_p) 161fda9279dSmrg{ 162fda9279dSmrg struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); 163fda9279dSmrg struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix); 164fda9279dSmrg int ret; 165fda9279dSmrg int handle; 166fda9279dSmrg 167fda9279dSmrg ret = nouveau_bo_set_prime(bo, &handle); 168fda9279dSmrg if (ret != 0) { 169fda9279dSmrg ErrorF("%s: ret is %d errno is %d\n", __func__, ret, errno); 170fda9279dSmrg return FALSE; 171fda9279dSmrg } 172fda9279dSmrg nvpix->shared = TRUE; 173fda9279dSmrg *handle_p = (void *)(long)handle; 174fda9279dSmrg return TRUE; 175fda9279dSmrg} 176fda9279dSmrg 177fda9279dSmrgstatic Bool 178fda9279dSmrgnouveau_exa_set_shared_pixmap_backing(PixmapPtr ppix, void *handle) 179fda9279dSmrg{ 180fda9279dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); 181fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 182fda9279dSmrg struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); 183fda9279dSmrg struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix); 184fda9279dSmrg int ret; 185fda9279dSmrg int ihandle = (int)(long)(handle); 186fda9279dSmrg 187fda9279dSmrg ret = nouveau_bo_prime_handle_ref(pNv->dev, ihandle, &bo); 188fda9279dSmrg if (ret) { 189fda9279dSmrg ErrorF("failed to get BO with handle %d\n", ihandle); 190fda9279dSmrg return FALSE; 191fda9279dSmrg } 192fda9279dSmrg nvpix->bo = bo; 193fda9279dSmrg nvpix->shared = TRUE; 194fda9279dSmrg close(ihandle); 195fda9279dSmrg return TRUE; 196fda9279dSmrg} 197fda9279dSmrg#endif 198fda9279dSmrg 199fda9279dSmrgbool 200fda9279dSmrgnv50_style_tiled_pixmap(PixmapPtr ppix) 201fda9279dSmrg{ 202fda9279dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); 203fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 204fda9279dSmrg 205fda9279dSmrg return pNv->Architecture >= NV_TESLA && 206fda9279dSmrg nouveau_pixmap_bo(ppix)->config.nv50.memtype; 207fda9279dSmrg} 208fda9279dSmrg 209fda9279dSmrgstatic int 210fda9279dSmrgnouveau_exa_scratch(NVPtr pNv, int size, struct nouveau_bo **pbo, int *off) 211fda9279dSmrg{ 212fda9279dSmrg struct nouveau_bo *bo; 213fda9279dSmrg int ret; 214fda9279dSmrg 215fda9279dSmrg if (!pNv->transfer || 216fda9279dSmrg pNv->transfer->size <= pNv->transfer_offset + size) { 217fda9279dSmrg ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 218fda9279dSmrg 0, NOUVEAU_ALIGN(size, 1 * 1024 * 1024), 219fda9279dSmrg NULL, &bo); 220fda9279dSmrg if (ret != 0) 221fda9279dSmrg return ret; 222fda9279dSmrg 223fda9279dSmrg ret = nouveau_bo_map(bo, NOUVEAU_BO_RDWR, pNv->client); 224fda9279dSmrg if (ret != 0) { 225fda9279dSmrg nouveau_bo_ref(NULL, &bo); 226fda9279dSmrg return ret; 227fda9279dSmrg } 228fda9279dSmrg 229fda9279dSmrg nouveau_bo_ref(bo, &pNv->transfer); 230fda9279dSmrg nouveau_bo_ref(NULL, &bo); 231fda9279dSmrg pNv->transfer_offset = 0; 232fda9279dSmrg } 233fda9279dSmrg 234fda9279dSmrg *off = pNv->transfer_offset; 235fda9279dSmrg *pbo = pNv->transfer; 236fda9279dSmrg 237fda9279dSmrg pNv->transfer_offset += size; 238fda9279dSmrg return 0; 239fda9279dSmrg} 240fda9279dSmrg 241fda9279dSmrgstatic Bool 242fda9279dSmrgnouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h, 243fda9279dSmrg char *dst, int dst_pitch) 244fda9279dSmrg{ 245fda9279dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pspix->drawable.pScreen); 246fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 247fda9279dSmrg struct nouveau_bo *bo; 248fda9279dSmrg int src_pitch, tmp_pitch, cpp, i; 249fda9279dSmrg const char *src; 250fda9279dSmrg Bool ret; 251fda9279dSmrg 252fda9279dSmrg cpp = pspix->drawable.bitsPerPixel >> 3; 253fda9279dSmrg src_pitch = exaGetPixmapPitch(pspix); 254fda9279dSmrg tmp_pitch = w * cpp; 255fda9279dSmrg 256fda9279dSmrg while (h) { 257fda9279dSmrg const int lines = (h > 2047) ? 2047 : h; 258fda9279dSmrg struct nouveau_bo *tmp; 259fda9279dSmrg int tmp_offset; 260fda9279dSmrg 261fda9279dSmrg if (nouveau_exa_scratch(pNv, lines * tmp_pitch, 262fda9279dSmrg &tmp, &tmp_offset)) 263fda9279dSmrg goto memcpy; 264fda9279dSmrg 265fda9279dSmrg if (!NVAccelM2MF(pNv, w, lines, cpp, 0, tmp_offset, 266fda9279dSmrg nouveau_pixmap_bo(pspix), NOUVEAU_BO_VRAM, 267fda9279dSmrg src_pitch, pspix->drawable.height, x, y, 268fda9279dSmrg tmp, NOUVEAU_BO_GART, tmp_pitch, 269fda9279dSmrg lines, 0, 0)) 270fda9279dSmrg goto memcpy; 271fda9279dSmrg 272fda9279dSmrg nouveau_bo_wait(tmp, NOUVEAU_BO_RD, pNv->client); 273fda9279dSmrg if (dst_pitch == tmp_pitch) { 274fda9279dSmrg memcpy(dst, tmp->map + tmp_offset, dst_pitch * lines); 275fda9279dSmrg dst += dst_pitch * lines; 276fda9279dSmrg } else { 277fda9279dSmrg src = tmp->map + tmp_offset; 278fda9279dSmrg for (i = 0; i < lines; i++) { 279fda9279dSmrg memcpy(dst, src, tmp_pitch); 280fda9279dSmrg src += tmp_pitch; 281fda9279dSmrg dst += dst_pitch; 282fda9279dSmrg } 283fda9279dSmrg } 284fda9279dSmrg 285fda9279dSmrg /* next! */ 286fda9279dSmrg h -= lines; 287fda9279dSmrg y += lines; 288fda9279dSmrg } 289fda9279dSmrg return TRUE; 290fda9279dSmrg 291fda9279dSmrgmemcpy: 292fda9279dSmrg bo = nouveau_pixmap_bo(pspix); 293fda9279dSmrg if (nv50_style_tiled_pixmap(pspix)) 294fda9279dSmrg ErrorF("%s:%d - falling back to memcpy ignores tiling\n", 295fda9279dSmrg __func__, __LINE__); 296fda9279dSmrg 297fda9279dSmrg if (nouveau_bo_map(bo, NOUVEAU_BO_RD, pNv->client)) 298fda9279dSmrg return FALSE; 299fda9279dSmrg src = (char *)bo->map + (y * src_pitch) + (x * cpp); 300fda9279dSmrg ret = NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp); 301fda9279dSmrg return ret; 302fda9279dSmrg} 303fda9279dSmrg 304fda9279dSmrgstatic Bool 305fda9279dSmrgnouveau_exa_upload_to_screen(PixmapPtr pdpix, int x, int y, int w, int h, 306fda9279dSmrg char *src, int src_pitch) 307fda9279dSmrg{ 308fda9279dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pdpix->drawable.pScreen); 309fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 310fda9279dSmrg int dst_pitch, tmp_pitch, cpp, i; 311fda9279dSmrg struct nouveau_bo *bo; 312fda9279dSmrg char *dst; 313fda9279dSmrg Bool ret; 314fda9279dSmrg 315fda9279dSmrg cpp = pdpix->drawable.bitsPerPixel >> 3; 316fda9279dSmrg dst_pitch = exaGetPixmapPitch(pdpix); 317fda9279dSmrg tmp_pitch = w * cpp; 318fda9279dSmrg 319fda9279dSmrg /* try hostdata transfer */ 320fda9279dSmrg if (w * h * cpp < 16*1024) /* heuristic */ 321fda9279dSmrg { 322fda9279dSmrg if (pNv->Architecture < NV_TESLA) { 323fda9279dSmrg if (NV04EXAUploadIFC(pScrn, src, src_pitch, pdpix, 324fda9279dSmrg x, y, w, h, cpp)) { 325fda9279dSmrg return TRUE; 326fda9279dSmrg } 327fda9279dSmrg } else 328fda9279dSmrg if (pNv->Architecture < NV_FERMI) { 329fda9279dSmrg if (NV50EXAUploadSIFC(src, src_pitch, pdpix, 330fda9279dSmrg x, y, w, h, cpp)) { 331fda9279dSmrg return TRUE; 332fda9279dSmrg } 333fda9279dSmrg } else { 334fda9279dSmrg if (NVC0EXAUploadSIFC(src, src_pitch, pdpix, 335fda9279dSmrg x, y, w, h, cpp)) { 336fda9279dSmrg return TRUE; 337fda9279dSmrg } 338fda9279dSmrg } 339fda9279dSmrg } 340fda9279dSmrg 341fda9279dSmrg while (h) { 342fda9279dSmrg const int lines = (h > 2047) ? 2047 : h; 343fda9279dSmrg struct nouveau_bo *tmp; 344fda9279dSmrg int tmp_offset; 345fda9279dSmrg 346fda9279dSmrg if (nouveau_exa_scratch(pNv, lines * tmp_pitch, 347fda9279dSmrg &tmp, &tmp_offset)) 348fda9279dSmrg goto memcpy; 349fda9279dSmrg 350fda9279dSmrg if (src_pitch == tmp_pitch) { 351fda9279dSmrg memcpy(tmp->map + tmp_offset, src, src_pitch * lines); 352fda9279dSmrg src += src_pitch * lines; 353fda9279dSmrg } else { 354fda9279dSmrg dst = tmp->map + tmp_offset; 355fda9279dSmrg for (i = 0; i < lines; i++) { 356fda9279dSmrg memcpy(dst, src, tmp_pitch); 357fda9279dSmrg src += src_pitch; 358fda9279dSmrg dst += tmp_pitch; 359fda9279dSmrg } 360fda9279dSmrg } 361fda9279dSmrg 362fda9279dSmrg if (!NVAccelM2MF(pNv, w, lines, cpp, tmp_offset, 0, tmp, 363fda9279dSmrg NOUVEAU_BO_GART, tmp_pitch, lines, 0, 0, 364fda9279dSmrg nouveau_pixmap_bo(pdpix), NOUVEAU_BO_VRAM, 365fda9279dSmrg dst_pitch, pdpix->drawable.height, x, y)) 366fda9279dSmrg goto memcpy; 367fda9279dSmrg 368fda9279dSmrg /* next! */ 369fda9279dSmrg h -= lines; 370fda9279dSmrg y += lines; 371fda9279dSmrg } 372fda9279dSmrg 373fda9279dSmrg return TRUE; 374fda9279dSmrg 375fda9279dSmrg /* fallback to memcpy-based transfer */ 376fda9279dSmrgmemcpy: 377fda9279dSmrg bo = nouveau_pixmap_bo(pdpix); 378fda9279dSmrg if (nv50_style_tiled_pixmap(pdpix)) 379fda9279dSmrg ErrorF("%s:%d - falling back to memcpy ignores tiling\n", 380fda9279dSmrg __func__, __LINE__); 381fda9279dSmrg 382fda9279dSmrg if (nouveau_bo_map(bo, NOUVEAU_BO_WR, pNv->client)) 383fda9279dSmrg return FALSE; 384fda9279dSmrg dst = (char *)bo->map + (y * dst_pitch) + (x * cpp); 385fda9279dSmrg ret = NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp); 386fda9279dSmrg return ret; 387fda9279dSmrg} 388fda9279dSmrg 389fda9279dSmrgBool 390fda9279dSmrgnouveau_exa_pixmap_is_onscreen(PixmapPtr ppix) 391fda9279dSmrg{ 392fda9279dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); 393fda9279dSmrg 394fda9279dSmrg if (pScrn->pScreen->GetScreenPixmap(pScrn->pScreen) == ppix) 395fda9279dSmrg return TRUE; 396fda9279dSmrg 397fda9279dSmrg return FALSE; 398fda9279dSmrg} 399fda9279dSmrg 400fda9279dSmrgstatic void 401fda9279dSmrgnouveau_exa_flush(ScrnInfoPtr pScrn) 402fda9279dSmrg{ 403fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 404fda9279dSmrg nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); 405fda9279dSmrg} 406fda9279dSmrg 407fda9279dSmrgBool 408fda9279dSmrgnouveau_exa_init(ScreenPtr pScreen) 409fda9279dSmrg{ 410fda9279dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 411fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 412fda9279dSmrg ExaDriverPtr exa; 413fda9279dSmrg 414fda9279dSmrg if (!xf86LoadSubModule(pScrn, "exa")) 415fda9279dSmrg return FALSE; 416fda9279dSmrg 417fda9279dSmrg exa = exaDriverAlloc(); 418fda9279dSmrg if (!exa) 419fda9279dSmrg return FALSE; 420fda9279dSmrg 421fda9279dSmrg exa->exa_major = EXA_VERSION_MAJOR; 422fda9279dSmrg exa->exa_minor = EXA_VERSION_MINOR; 423fda9279dSmrg exa->flags = EXA_OFFSCREEN_PIXMAPS; 424fda9279dSmrg 425fda9279dSmrg#ifdef EXA_SUPPORTS_PREPARE_AUX 426fda9279dSmrg exa->flags |= EXA_SUPPORTS_PREPARE_AUX; 427fda9279dSmrg#endif 428fda9279dSmrg 429fda9279dSmrg exa->PixmapIsOffscreen = nouveau_exa_pixmap_is_offscreen; 430fda9279dSmrg exa->PrepareAccess = nouveau_exa_prepare_access; 431fda9279dSmrg exa->FinishAccess = nouveau_exa_finish_access; 432fda9279dSmrg 433fda9279dSmrg exa->flags |= (EXA_HANDLES_PIXMAPS | EXA_MIXED_PIXMAPS); 434fda9279dSmrg exa->pixmapOffsetAlign = 256; 435fda9279dSmrg exa->pixmapPitchAlign = 64; 436fda9279dSmrg 437fda9279dSmrg exa->CreatePixmap2 = nouveau_exa_create_pixmap; 438fda9279dSmrg exa->DestroyPixmap = nouveau_exa_destroy_pixmap; 439fda9279dSmrg#ifdef NOUVEAU_PIXMAP_SHARING 440fda9279dSmrg exa->SharePixmapBacking = nouveau_exa_share_pixmap_backing; 441fda9279dSmrg exa->SetSharedPixmapBacking = nouveau_exa_set_shared_pixmap_backing; 442fda9279dSmrg#endif 443fda9279dSmrg 444fda9279dSmrg if (pNv->Architecture >= NV_TESLA) { 445fda9279dSmrg exa->maxX = 8192; 446fda9279dSmrg exa->maxY = 8192; 447fda9279dSmrg } else 448fda9279dSmrg if (pNv->Architecture >= NV_ARCH_10) { 449fda9279dSmrg exa->maxX = 4096; 450fda9279dSmrg exa->maxY = 4096; 451fda9279dSmrg } else { 452fda9279dSmrg exa->maxX = 2048; 453fda9279dSmrg exa->maxY = 2048; 454fda9279dSmrg } 455fda9279dSmrg 456fda9279dSmrg exa->MarkSync = nouveau_exa_mark_sync; 457fda9279dSmrg exa->WaitMarker = nouveau_exa_wait_marker; 458fda9279dSmrg 459fda9279dSmrg exa->DownloadFromScreen = nouveau_exa_download_from_screen; 460fda9279dSmrg exa->UploadToScreen = nouveau_exa_upload_to_screen; 461fda9279dSmrg 462fda9279dSmrg if (pNv->Architecture < NV_TESLA) { 463fda9279dSmrg exa->PrepareCopy = NV04EXAPrepareCopy; 464fda9279dSmrg exa->Copy = NV04EXACopy; 465fda9279dSmrg exa->DoneCopy = NV04EXADoneCopy; 466fda9279dSmrg 467fda9279dSmrg exa->PrepareSolid = NV04EXAPrepareSolid; 468fda9279dSmrg exa->Solid = NV04EXASolid; 469fda9279dSmrg exa->DoneSolid = NV04EXADoneSolid; 470fda9279dSmrg } else 471fda9279dSmrg if (pNv->Architecture < NV_FERMI) { 472fda9279dSmrg exa->PrepareCopy = NV50EXAPrepareCopy; 473fda9279dSmrg exa->Copy = NV50EXACopy; 474fda9279dSmrg exa->DoneCopy = NV50EXADoneCopy; 475fda9279dSmrg 476fda9279dSmrg exa->PrepareSolid = NV50EXAPrepareSolid; 477fda9279dSmrg exa->Solid = NV50EXASolid; 478fda9279dSmrg exa->DoneSolid = NV50EXADoneSolid; 479fda9279dSmrg } else { 480fda9279dSmrg exa->PrepareCopy = NVC0EXAPrepareCopy; 481fda9279dSmrg exa->Copy = NVC0EXACopy; 482fda9279dSmrg exa->DoneCopy = NVC0EXADoneCopy; 483fda9279dSmrg 484fda9279dSmrg exa->PrepareSolid = NVC0EXAPrepareSolid; 485fda9279dSmrg exa->Solid = NVC0EXASolid; 486fda9279dSmrg exa->DoneSolid = NVC0EXADoneSolid; 487fda9279dSmrg } 488fda9279dSmrg 489fda9279dSmrg switch (pNv->Architecture) { 490fda9279dSmrg case NV_ARCH_10: 491fda9279dSmrg case NV_ARCH_20: 492fda9279dSmrg exa->CheckComposite = NV10EXACheckComposite; 493fda9279dSmrg exa->PrepareComposite = NV10EXAPrepareComposite; 494fda9279dSmrg exa->Composite = NV10EXAComposite; 495fda9279dSmrg exa->DoneComposite = NV10EXADoneComposite; 496fda9279dSmrg break; 497fda9279dSmrg case NV_ARCH_30: 498fda9279dSmrg exa->CheckComposite = NV30EXACheckComposite; 499fda9279dSmrg exa->PrepareComposite = NV30EXAPrepareComposite; 500fda9279dSmrg exa->Composite = NV30EXAComposite; 501fda9279dSmrg exa->DoneComposite = NV30EXADoneComposite; 502fda9279dSmrg break; 503fda9279dSmrg case NV_ARCH_40: 504fda9279dSmrg exa->CheckComposite = NV40EXACheckComposite; 505fda9279dSmrg exa->PrepareComposite = NV40EXAPrepareComposite; 506fda9279dSmrg exa->Composite = NV40EXAComposite; 507fda9279dSmrg exa->DoneComposite = NV40EXADoneComposite; 508fda9279dSmrg break; 509fda9279dSmrg case NV_TESLA: 510fda9279dSmrg exa->CheckComposite = NV50EXACheckComposite; 511fda9279dSmrg exa->PrepareComposite = NV50EXAPrepareComposite; 512fda9279dSmrg exa->Composite = NV50EXAComposite; 513fda9279dSmrg exa->DoneComposite = NV50EXADoneComposite; 514fda9279dSmrg break; 515fda9279dSmrg case NV_FERMI: 516fda9279dSmrg case NV_KEPLER: 517cd34e0e1Smrg case NV_MAXWELL: 518cd34e0e1Smrg case NV_PASCAL: 519fda9279dSmrg exa->CheckComposite = NVC0EXACheckComposite; 520fda9279dSmrg exa->PrepareComposite = NVC0EXAPrepareComposite; 521fda9279dSmrg exa->Composite = NVC0EXAComposite; 522fda9279dSmrg exa->DoneComposite = NVC0EXADoneComposite; 523fda9279dSmrg break; 524fda9279dSmrg default: 525fda9279dSmrg break; 526fda9279dSmrg } 527fda9279dSmrg 528fda9279dSmrg if (!exaDriverInit(pScreen, exa)) 529fda9279dSmrg return FALSE; 530fda9279dSmrg 531fda9279dSmrg pNv->EXADriverPtr = exa; 532fda9279dSmrg pNv->Flush = nouveau_exa_flush; 533fda9279dSmrg return TRUE; 534fda9279dSmrg} 535