1/* 2 * Copyright 2008 Ben Skeggs 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 */ 22 23#include "nv_include.h" 24#include "nvc0_accel.h" 25 26#include "shader/xfrm2nvc0.vp" 27#include "shader/videonvc0.fp" 28 29#include "shader/exascnvc0.fp" 30#include "shader/exacmnvc0.fp" 31#include "shader/exacanvc0.fp" 32#include "shader/exasanvc0.fp" 33#include "shader/exas8nvc0.fp" 34#include "shader/exac8nvc0.fp" 35 36#include "shader/xfrm2nve0.vp" 37#include "shader/videonve0.fp" 38 39#include "shader/exascnve0.fp" 40#include "shader/exacmnve0.fp" 41#include "shader/exacanve0.fp" 42#include "shader/exasanve0.fp" 43#include "shader/exas8nve0.fp" 44#include "shader/exac8nve0.fp" 45 46#include "shader/xfrm2nvf0.vp" 47#include "shader/videonvf0.fp" 48 49#include "shader/exascnvf0.fp" 50#include "shader/exacmnvf0.fp" 51#include "shader/exacanvf0.fp" 52#include "shader/exasanvf0.fp" 53#include "shader/exas8nvf0.fp" 54#include "shader/exac8nvf0.fp" 55 56#include "shader/xfrm2nv110.vp" 57#include "shader/videonv110.fp" 58 59#include "shader/exascnv110.fp" 60#include "shader/exacmnv110.fp" 61#include "shader/exacanv110.fp" 62#include "shader/exasanv110.fp" 63#include "shader/exas8nv110.fp" 64#include "shader/exac8nv110.fp" 65 66#define NVC0PushProgram(pNv,addr,code) do { \ 67 const unsigned size = sizeof(code) / sizeof(code[0]); \ 68 PUSH_DATAu((pNv)->pushbuf, (pNv)->scratch, (addr), size); \ 69 PUSH_DATAp((pNv)->pushbuf, (code), size); \ 70} while(0) 71 72void 73NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box) 74{ 75 ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); 76 NVPtr pNv = NVPTR(pScrn); 77 struct nouveau_pushbuf *push = pNv->pushbuf; 78 int head; 79 xf86CrtcPtr crtc; 80 81 if (!pNv->NvSW || !nouveau_exa_pixmap_is_onscreen(ppix)) 82 return; 83 84 crtc = nouveau_pick_best_crtc(pScrn, box->x1, box->y1, 85 box->x2 - box->x1, 86 box->y2 - box->y1); 87 if (!crtc) 88 return; 89 90 if (!PUSH_SPACE(push, 32)) 91 return; 92 93 head = drmmode_head(crtc); 94 95 BEGIN_NVC0(push, NV01_SUBC(NVSW, OBJECT), 1); 96 PUSH_DATA (push, pNv->NvSW->handle); 97 BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4); 98 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32); 99 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET)); 100 PUSH_DATA (push, 0x22222222); 101 PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); 102 BEGIN_NVC0(push, SUBC_NVSW(0x0400), 4); 103 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32); 104 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET)); 105 PUSH_DATA (push, 0x11111111); 106 PUSH_DATA (push, head); 107 BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4); 108 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32); 109 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET)); 110 PUSH_DATA (push, 0x11111111); 111 PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); 112} 113 114Bool 115NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn) 116{ 117 NVPtr pNv = NVPTR(pScrn); 118 struct nouveau_pushbuf *push = pNv->pushbuf; 119 int ret; 120 121 ret = nouveau_object_new(pNv->channel, 0x00009039, 0x9039, 122 NULL, 0, &pNv->NvMemFormat); 123 if (ret) 124 return FALSE; 125 126 BEGIN_NVC0(push, NV01_SUBC(M2MF, OBJECT), 1); 127 PUSH_DATA (push, pNv->NvMemFormat->handle); 128 BEGIN_NVC0(push, NVC0_M2MF(QUERY_ADDRESS_HIGH), 3); 129 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET) >> 32); 130 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET)); 131 PUSH_DATA (push, 0); 132 133 return TRUE; 134} 135 136Bool 137NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn) 138{ 139 NVPtr pNv = NVPTR(pScrn); 140 struct nouveau_pushbuf *push = pNv->pushbuf; 141 uint32_t class = (pNv->dev->chipset < 0xf0) ? 0xa040 : 0xa140; 142 int ret; 143 144 ret = nouveau_object_new(pNv->channel, class, class, NULL, 0, 145 &pNv->NvMemFormat); 146 if (ret) 147 return FALSE; 148 149 BEGIN_NVC0(push, NV01_SUBC(P2MF, OBJECT), 1); 150 PUSH_DATA (push, pNv->NvMemFormat->handle); 151 return TRUE; 152} 153 154Bool 155NVAccelInitCOPY_NVE0(ScrnInfoPtr pScrn) 156{ 157 NVPtr pNv = NVPTR(pScrn); 158 struct nouveau_pushbuf *push = pNv->pushbuf; 159 uint32_t class; 160 int ret; 161 162 if (pNv->dev->chipset < 0x110) 163 class = 0xa0b5; 164 else if (pNv->dev->chipset < 0x130) 165 class = 0xb0b5; 166 else 167 class = 0xc0b5; 168 169 ret = nouveau_object_new(pNv->channel, class, class, 170 NULL, 0, &pNv->NvCOPY); 171 if (ret) 172 return FALSE; 173 174 BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1); 175 PUSH_DATA (push, pNv->NvCOPY->handle); 176 return TRUE; 177} 178 179Bool 180NVAccelInit2D_NVC0(ScrnInfoPtr pScrn) 181{ 182 NVPtr pNv = NVPTR(pScrn); 183 struct nouveau_pushbuf *push = pNv->pushbuf; 184 int ret; 185 186 ret = nouveau_object_new(pNv->channel, 0x0000902d, 0x902d, 187 NULL, 0, &pNv->Nv2D); 188 if (ret) 189 return FALSE; 190 191 if (!PUSH_SPACE(push, 64)) 192 return FALSE; 193 194 BEGIN_NVC0(push, NV01_SUBC(2D, OBJECT), 1); 195 PUSH_DATA (push, pNv->Nv2D->handle); 196 197 BEGIN_NVC0(push, NV50_2D(CLIP_ENABLE), 1); 198 PUSH_DATA (push, 1); 199 BEGIN_NVC0(push, NV50_2D(COLOR_KEY_ENABLE), 1); 200 PUSH_DATA (push, 0); 201 BEGIN_NVC0(push, NV50_2D(UNK0884), 1); 202 PUSH_DATA (push, 0x3f); 203 BEGIN_NVC0(push, NV50_2D(UNK0888), 1); 204 PUSH_DATA (push, 1); 205 BEGIN_NVC0(push, NV50_2D(ROP), 1); 206 PUSH_DATA (push, 0x55); 207 BEGIN_NVC0(push, NV50_2D(OPERATION), 1); 208 PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); 209 210 BEGIN_NVC0(push, NV50_2D(BLIT_DU_DX_FRACT), 4); 211 PUSH_DATA (push, 0); 212 PUSH_DATA (push, 1); 213 PUSH_DATA (push, 0); 214 PUSH_DATA (push, 1); 215 BEGIN_NVC0(push, NV50_2D(DRAW_SHAPE), 2); 216 PUSH_DATA (push, 4); 217 PUSH_DATA (push, NV50_SURFACE_FORMAT_B5G6R5_UNORM); 218 BEGIN_NVC0(push, NV50_2D(PATTERN_COLOR_FORMAT), 2); 219 PUSH_DATA (push, 2); 220 PUSH_DATA (push, 1); 221 222 pNv->currentRop = 0xfffffffa; 223 return TRUE; 224} 225 226Bool 227NVAccelInit3D_NVC0(ScrnInfoPtr pScrn) 228{ 229 NVPtr pNv = NVPTR(pScrn); 230 struct nouveau_pushbuf *push = pNv->pushbuf; 231 struct nouveau_bo *bo = pNv->scratch; 232 uint32_t class, handle; 233 int ret; 234 235 if (pNv->Architecture < NV_KEPLER) { 236 class = 0x9097; 237 handle = 0x001f906e; 238 } else if (pNv->dev->chipset == 0xea) { 239 class = 0xa297; 240 handle = 0x0000906e; 241 } else if (pNv->dev->chipset < 0xf0) { 242 class = 0xa097; 243 handle = 0x0000906e; 244 } else if (pNv->dev->chipset < 0x110) { 245 class = 0xa197; 246 handle = 0x0000906e; 247 } else if (pNv->dev->chipset < 0x120) { 248 class = 0xb097; 249 handle = 0x0000906e; 250 } else if (pNv->dev->chipset < 0x130) { 251 class = 0xb197; 252 handle = 0x0000906e; 253 } else if (pNv->dev->chipset == 0x130) { 254 class = 0xc097; 255 handle = 0x0000906e; 256 } else if (pNv->dev->chipset < 0x140) { 257 class = 0xc197; 258 handle = 0x0000906e; 259 } else { 260 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 261 "No 3D acceleration support for NV%X\n", 262 pNv->dev->chipset); 263 return FALSE; 264 } 265 266 ret = nouveau_object_new(pNv->channel, class, class, 267 NULL, 0, &pNv->Nv3D); 268 if (ret) 269 return FALSE; 270 271 ret = nouveau_object_new(pNv->channel, handle, 0x906e, 272 NULL, 0, &pNv->NvSW); 273 if (ret) { 274 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 275 "DRM doesn't support sync-to-vblank\n"); 276 } 277 278 if (nouveau_pushbuf_space(push, 512, 0, 0) || 279 nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) { 280 pNv->scratch, NOUVEAU_BO_VRAM | 281 NOUVEAU_BO_WR }, 1)) 282 return FALSE; 283 284 BEGIN_NVC0(push, NV01_SUBC(3D, OBJECT), 1); 285 PUSH_DATA (push, pNv->Nv3D->handle); 286 BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1); 287 PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS); 288 BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 3); 289 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET) >> 32); 290 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET)); 291 PUSH_DATA (push, 0); 292 BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1); 293 PUSH_DATA (push, 0); 294 BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); 295 PUSH_DATA (push, 0); 296 BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1); 297 PUSH_DATA (push, 0); 298 299 BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); 300 PUSH_DATA (push, (8192 << 16) | 0); 301 PUSH_DATA (push, (8192 << 16) | 0); 302 BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 303 PUSH_DATA (push, (8192 << 16) | 0); 304 PUSH_DATA (push, (8192 << 16) | 0); 305 BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 1); 306 PUSH_DATA (push, 1); 307 BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); 308 PUSH_DATA (push, 0); 309 BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1); 310 PUSH_DATA (push, 0); 311 312 BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3); 313 PUSH_DATA (push, (bo->offset + TIC_OFFSET) >> 32); 314 PUSH_DATA (push, (bo->offset + TIC_OFFSET)); 315 PUSH_DATA (push, 15); 316 BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3); 317 PUSH_DATA (push, (bo->offset + TSC_OFFSET) >> 32); 318 PUSH_DATA (push, (bo->offset + TSC_OFFSET)); 319 PUSH_DATA (push, 0); 320 BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1); 321 PUSH_DATA (push, 1); 322 if (pNv->Architecture < NV_KEPLER) { 323 BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(4)), 1); 324 PUSH_DATA (push, 0x54); 325 BEGIN_NIC0(push, NVC0_3D(BIND_TIC(4)), 2); 326 PUSH_DATA (push, (0 << 9) | (0 << 1) | NVC0_3D_BIND_TIC_ACTIVE); 327 PUSH_DATA (push, (1 << 9) | (1 << 1) | NVC0_3D_BIND_TIC_ACTIVE); 328 } else { 329 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 6); 330 PUSH_DATA (push, 256); 331 PUSH_DATA (push, (bo->offset + TB_OFFSET) >> 32); 332 PUSH_DATA (push, (bo->offset + TB_OFFSET)); 333 PUSH_DATA (push, 0); 334 PUSH_DATA (push, 0x00000000); 335 PUSH_DATA (push, 0x00000001); 336 BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1); 337 PUSH_DATA (push, 0x11); 338 BEGIN_NVC0(push, NVE4_3D(TEX_CB_INDEX), 1); 339 PUSH_DATA (push, 1); 340 } 341 342 if (pNv->Architecture < NV_MAXWELL) { 343 BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3); 344 PUSH_DATA (push, (bo->offset + MISC_OFFSET) >> 32); 345 PUSH_DATA (push, (bo->offset + MISC_OFFSET)); 346 PUSH_DATA (push, 1); 347 } else { 348 /* Use new TIC format. Not strictly necessary for GM20x+ */ 349 IMMED_NVC0(push, SUBC_3D(0x0f10), 1); 350 if (pNv->dev->chipset >= 0x120) { 351 /* Use center sample locations. */ 352 BEGIN_NVC0(push, SUBC_3D(0x11e0), 4); 353 PUSH_DATA (push, 0x88888888); 354 PUSH_DATA (push, 0x88888888); 355 PUSH_DATA (push, 0x88888888); 356 PUSH_DATA (push, 0x88888888); 357 } 358 } 359 360 BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2); 361 PUSH_DATA (push, (bo->offset + CODE_OFFSET) >> 32); 362 PUSH_DATA (push, (bo->offset + CODE_OFFSET)); 363 if (pNv->Architecture < NV_KEPLER) { 364 NVC0PushProgram(pNv, PVP_PASS, NVC0VP_Transform2); 365 NVC0PushProgram(pNv, PFP_S, NVC0FP_Source); 366 NVC0PushProgram(pNv, PFP_C, NVC0FP_Composite); 367 NVC0PushProgram(pNv, PFP_CCA, NVC0FP_CAComposite); 368 NVC0PushProgram(pNv, PFP_CCASA, NVC0FP_CACompositeSrcAlpha); 369 NVC0PushProgram(pNv, PFP_S_A8, NVC0FP_Source_A8); 370 NVC0PushProgram(pNv, PFP_C_A8, NVC0FP_Composite_A8); 371 NVC0PushProgram(pNv, PFP_NV12, NVC0FP_NV12); 372 373 BEGIN_NVC0(push, NVC0_3D(MEM_BARRIER), 1); 374 PUSH_DATA (push, 0x1111); 375 } else 376 if (pNv->dev->chipset < 0xf0 && pNv->dev->chipset != 0xea) { 377 NVC0PushProgram(pNv, PVP_PASS, NVE0VP_Transform2); 378 NVC0PushProgram(pNv, PFP_S, NVE0FP_Source); 379 NVC0PushProgram(pNv, PFP_C, NVE0FP_Composite); 380 NVC0PushProgram(pNv, PFP_CCA, NVE0FP_CAComposite); 381 NVC0PushProgram(pNv, PFP_CCASA, NVE0FP_CACompositeSrcAlpha); 382 NVC0PushProgram(pNv, PFP_S_A8, NVE0FP_Source_A8); 383 NVC0PushProgram(pNv, PFP_C_A8, NVE0FP_Composite_A8); 384 NVC0PushProgram(pNv, PFP_NV12, NVE0FP_NV12); 385 } else 386 if (pNv->dev->chipset < 0x110) { 387 NVC0PushProgram(pNv, PVP_PASS, NVF0VP_Transform2); 388 NVC0PushProgram(pNv, PFP_S, NVF0FP_Source); 389 NVC0PushProgram(pNv, PFP_C, NVF0FP_Composite); 390 NVC0PushProgram(pNv, PFP_CCA, NVF0FP_CAComposite); 391 NVC0PushProgram(pNv, PFP_CCASA, NVF0FP_CACompositeSrcAlpha); 392 NVC0PushProgram(pNv, PFP_S_A8, NVF0FP_Source_A8); 393 NVC0PushProgram(pNv, PFP_C_A8, NVF0FP_Composite_A8); 394 NVC0PushProgram(pNv, PFP_NV12, NVF0FP_NV12); 395 } else { 396 NVC0PushProgram(pNv, PVP_PASS, NV110VP_Transform2); 397 NVC0PushProgram(pNv, PFP_S, NV110FP_Source); 398 NVC0PushProgram(pNv, PFP_C, NV110FP_Composite); 399 NVC0PushProgram(pNv, PFP_CCA, NV110FP_CAComposite); 400 NVC0PushProgram(pNv, PFP_CCASA, NV110FP_CACompositeSrcAlpha); 401 NVC0PushProgram(pNv, PFP_S_A8, NV110FP_Source_A8); 402 NVC0PushProgram(pNv, PFP_C_A8, NV110FP_Composite_A8); 403 NVC0PushProgram(pNv, PFP_NV12, NV110FP_NV12); 404 } 405 406 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 4); 407 PUSH_DATA (push, NVC0_3D_SP_SELECT_PROGRAM_VP_B | 408 NVC0_3D_SP_SELECT_ENABLE); 409 PUSH_DATA (push, PVP_PASS); 410 PUSH_DATA (push, 0x00000000); 411 PUSH_DATA (push, 8); 412 BEGIN_NVC0(push, NVC0_3D(VERT_COLOR_CLAMP_EN), 1); 413 PUSH_DATA (push, 1); 414 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 415 PUSH_DATA (push, 256); 416 PUSH_DATA (push, (bo->offset + PVP_DATA) >> 32); 417 PUSH_DATA (push, (bo->offset + PVP_DATA)); 418 BEGIN_NVC0(push, NVC0_3D(CB_BIND(0)), 1); 419 PUSH_DATA (push, 0x01); 420 421 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 4); 422 PUSH_DATA (push, NVC0_3D_SP_SELECT_PROGRAM_FP | 423 NVC0_3D_SP_SELECT_ENABLE); 424 PUSH_DATA (push, PFP_S); 425 PUSH_DATA (push, 0x00000000); 426 PUSH_DATA (push, 8); 427 BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1); 428 PUSH_DATA (push, 0x11111111); 429 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 430 PUSH_DATA (push, 256); 431 PUSH_DATA (push, (bo->offset + PFP_DATA) >> 32); 432 PUSH_DATA (push, (bo->offset + PFP_DATA)); 433 BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1); 434 PUSH_DATA (push, 0x01); 435 436 return TRUE; 437} 438 439