nvc0_accel.c revision 16ee1e9a
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#define NVC0PushProgram(pNv,addr,code) do { \ 57 const unsigned size = sizeof(code) / sizeof(code[0]); \ 58 PUSH_DATAu((pNv)->pushbuf, (pNv)->scratch, (addr), size); \ 59 PUSH_DATAp((pNv)->pushbuf, (code), size); \ 60} while(0) 61 62void 63NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box) 64{ 65 ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); 66 NVPtr pNv = NVPTR(pScrn); 67 struct nouveau_pushbuf *push = pNv->pushbuf; 68 int head; 69 xf86CrtcPtr crtc; 70 71 if (!pNv->NvSW || !nouveau_exa_pixmap_is_onscreen(ppix)) 72 return; 73 74 crtc = nouveau_pick_best_crtc(pScrn, FALSE, box->x1, box->y1, 75 box->x2 - box->x1, 76 box->y2 - box->y1); 77 if (!crtc) 78 return; 79 80 if (!PUSH_SPACE(push, 32)) 81 return; 82 83 head = drmmode_head(crtc); 84 85 BEGIN_NVC0(push, NV01_SUBC(NVSW, OBJECT), 1); 86 PUSH_DATA (push, pNv->NvSW->handle); 87 BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4); 88 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32); 89 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET)); 90 PUSH_DATA (push, 0x22222222); 91 PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); 92 BEGIN_NVC0(push, SUBC_NVSW(0x0400), 4); 93 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32); 94 PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET)); 95 PUSH_DATA (push, 0x11111111); 96 PUSH_DATA (push, head); 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, 0x11111111); 101 PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); 102} 103 104Bool 105NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn) 106{ 107 NVPtr pNv = NVPTR(pScrn); 108 struct nouveau_pushbuf *push = pNv->pushbuf; 109 int ret; 110 111 ret = nouveau_object_new(pNv->channel, 0x00009039, 0x9039, 112 NULL, 0, &pNv->NvMemFormat); 113 if (ret) 114 return FALSE; 115 116 BEGIN_NVC0(push, NV01_SUBC(M2MF, OBJECT), 1); 117 PUSH_DATA (push, pNv->NvMemFormat->handle); 118 BEGIN_NVC0(push, NVC0_M2MF(QUERY_ADDRESS_HIGH), 3); 119 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET) >> 32); 120 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET)); 121 PUSH_DATA (push, 0); 122 123 return TRUE; 124} 125 126Bool 127NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn) 128{ 129 NVPtr pNv = NVPTR(pScrn); 130 struct nouveau_pushbuf *push = pNv->pushbuf; 131 uint32_t class = (pNv->dev->chipset < 0xf0) ? 0xa040 : 0xa140; 132 int ret; 133 134 ret = nouveau_object_new(pNv->channel, class, class, NULL, 0, 135 &pNv->NvMemFormat); 136 if (ret) 137 return FALSE; 138 139 BEGIN_NVC0(push, NV01_SUBC(P2MF, OBJECT), 1); 140 PUSH_DATA (push, pNv->NvMemFormat->handle); 141 return TRUE; 142} 143 144Bool 145NVAccelInitCOPY_NVE0(ScrnInfoPtr pScrn) 146{ 147 NVPtr pNv = NVPTR(pScrn); 148 struct nouveau_pushbuf *push = pNv->pushbuf; 149 int ret; 150 151 ret = nouveau_object_new(pNv->channel, 0x0000a0b5, 0xa0b5, 152 NULL, 0, &pNv->NvCOPY); 153 if (ret) 154 return FALSE; 155 156 BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1); 157 PUSH_DATA (push, pNv->NvCOPY->handle); 158 return TRUE; 159} 160 161Bool 162NVAccelInit2D_NVC0(ScrnInfoPtr pScrn) 163{ 164 NVPtr pNv = NVPTR(pScrn); 165 struct nouveau_pushbuf *push = pNv->pushbuf; 166 int ret; 167 168 ret = nouveau_object_new(pNv->channel, 0x0000902d, 0x902d, 169 NULL, 0, &pNv->Nv2D); 170 if (ret) 171 return FALSE; 172 173 if (!PUSH_SPACE(push, 64)) 174 return FALSE; 175 176 BEGIN_NVC0(push, NV01_SUBC(2D, OBJECT), 1); 177 PUSH_DATA (push, pNv->Nv2D->handle); 178 179 BEGIN_NVC0(push, NV50_2D(CLIP_ENABLE), 1); 180 PUSH_DATA (push, 1); 181 BEGIN_NVC0(push, NV50_2D(COLOR_KEY_ENABLE), 1); 182 PUSH_DATA (push, 0); 183 BEGIN_NVC0(push, NV50_2D(UNK0884), 1); 184 PUSH_DATA (push, 0x3f); 185 BEGIN_NVC0(push, NV50_2D(UNK0888), 1); 186 PUSH_DATA (push, 1); 187 BEGIN_NVC0(push, NV50_2D(ROP), 1); 188 PUSH_DATA (push, 0x55); 189 BEGIN_NVC0(push, NV50_2D(OPERATION), 1); 190 PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); 191 192 BEGIN_NVC0(push, NV50_2D(BLIT_DU_DX_FRACT), 4); 193 PUSH_DATA (push, 0); 194 PUSH_DATA (push, 1); 195 PUSH_DATA (push, 0); 196 PUSH_DATA (push, 1); 197 BEGIN_NVC0(push, NV50_2D(DRAW_SHAPE), 2); 198 PUSH_DATA (push, 4); 199 PUSH_DATA (push, NV50_SURFACE_FORMAT_B5G6R5_UNORM); 200 BEGIN_NVC0(push, NV50_2D(PATTERN_COLOR_FORMAT), 2); 201 PUSH_DATA (push, 2); 202 PUSH_DATA (push, 1); 203 204 pNv->currentRop = 0xfffffffa; 205 return TRUE; 206} 207 208Bool 209NVAccelInit3D_NVC0(ScrnInfoPtr pScrn) 210{ 211 NVPtr pNv = NVPTR(pScrn); 212 struct nouveau_pushbuf *push = pNv->pushbuf; 213 struct nouveau_bo *bo = pNv->scratch; 214 uint32_t class, handle; 215 int ret; 216 217 if (pNv->Architecture < NV_KEPLER) { 218 class = 0x9097; 219 handle = 0x001f906e; 220 } else if (pNv->dev->chipset == 0xea) { 221 class = 0xa297; 222 handle = 0x0000906e; 223 } else if (pNv->dev->chipset < 0xf0) { 224 class = 0xa097; 225 handle = 0x0000906e; 226 } else { 227 class = 0xa197; 228 handle = 0x0000906e; 229 } 230 231 ret = nouveau_object_new(pNv->channel, class, class, 232 NULL, 0, &pNv->Nv3D); 233 if (ret) 234 return FALSE; 235 236 ret = nouveau_object_new(pNv->channel, handle, 0x906e, 237 NULL, 0, &pNv->NvSW); 238 if (ret) { 239 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 240 "DRM doesn't support sync-to-vblank\n"); 241 } 242 243 if (nouveau_pushbuf_space(push, 512, 0, 0) || 244 nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) { 245 pNv->scratch, NOUVEAU_BO_VRAM | 246 NOUVEAU_BO_WR }, 1)) 247 return FALSE; 248 249 BEGIN_NVC0(push, NV01_SUBC(3D, OBJECT), 1); 250 PUSH_DATA (push, pNv->Nv3D->handle); 251 BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1); 252 PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS); 253 BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 3); 254 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET) >> 32); 255 PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET)); 256 PUSH_DATA (push, 0); 257 BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1); 258 PUSH_DATA (push, 0); 259 BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); 260 PUSH_DATA (push, 0); 261 BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1); 262 PUSH_DATA (push, 0); 263 264 BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); 265 PUSH_DATA (push, (8192 << 16) | 0); 266 PUSH_DATA (push, (8192 << 16) | 0); 267 BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 268 PUSH_DATA (push, (8192 << 16) | 0); 269 PUSH_DATA (push, (8192 << 16) | 0); 270 BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 1); 271 PUSH_DATA (push, 1); 272 BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); 273 PUSH_DATA (push, 0); 274 BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1); 275 PUSH_DATA (push, 0); 276 277 BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3); 278 PUSH_DATA (push, (bo->offset + TIC_OFFSET) >> 32); 279 PUSH_DATA (push, (bo->offset + TIC_OFFSET)); 280 PUSH_DATA (push, 15); 281 BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3); 282 PUSH_DATA (push, (bo->offset + TSC_OFFSET) >> 32); 283 PUSH_DATA (push, (bo->offset + TSC_OFFSET)); 284 PUSH_DATA (push, 0); 285 BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1); 286 PUSH_DATA (push, 1); 287 if (pNv->Architecture < NV_KEPLER) { 288 BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(4)), 1); 289 PUSH_DATA (push, 0x54); 290 BEGIN_NIC0(push, NVC0_3D(BIND_TIC(4)), 2); 291 PUSH_DATA (push, (0 << 9) | (0 << 1) | NVC0_3D_BIND_TIC_ACTIVE); 292 PUSH_DATA (push, (1 << 9) | (1 << 1) | NVC0_3D_BIND_TIC_ACTIVE); 293 } else { 294 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 6); 295 PUSH_DATA (push, 256); 296 PUSH_DATA (push, (bo->offset + TB_OFFSET) >> 32); 297 PUSH_DATA (push, (bo->offset + TB_OFFSET)); 298 PUSH_DATA (push, 0); 299 PUSH_DATA (push, 0x00000000); 300 PUSH_DATA (push, 0x00000001); 301 BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1); 302 PUSH_DATA (push, 0x11); 303 BEGIN_NVC0(push, SUBC_3D(0x2608), 1); 304 PUSH_DATA (push, 1); 305 } 306 307 BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3); 308 PUSH_DATA (push, (bo->offset + MISC_OFFSET) >> 32); 309 PUSH_DATA (push, (bo->offset + MISC_OFFSET)); 310 PUSH_DATA (push, 1); 311 312 BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2); 313 PUSH_DATA (push, (bo->offset + CODE_OFFSET) >> 32); 314 PUSH_DATA (push, (bo->offset + CODE_OFFSET)); 315 if (pNv->Architecture < NV_KEPLER) { 316 NVC0PushProgram(pNv, PVP_PASS, NVC0VP_Transform2); 317 NVC0PushProgram(pNv, PFP_S, NVC0FP_Source); 318 NVC0PushProgram(pNv, PFP_C, NVC0FP_Composite); 319 NVC0PushProgram(pNv, PFP_CCA, NVC0FP_CAComposite); 320 NVC0PushProgram(pNv, PFP_CCASA, NVC0FP_CACompositeSrcAlpha); 321 NVC0PushProgram(pNv, PFP_S_A8, NVC0FP_Source_A8); 322 NVC0PushProgram(pNv, PFP_C_A8, NVC0FP_Composite_A8); 323 NVC0PushProgram(pNv, PFP_NV12, NVC0FP_NV12); 324 325 BEGIN_NVC0(push, NVC0_3D(MEM_BARRIER), 1); 326 PUSH_DATA (push, 0x1111); 327 } else 328 if (pNv->dev->chipset < 0xf0 && pNv->dev->chipset != 0xea) { 329 NVC0PushProgram(pNv, PVP_PASS, NVE0VP_Transform2); 330 NVC0PushProgram(pNv, PFP_S, NVE0FP_Source); 331 NVC0PushProgram(pNv, PFP_C, NVE0FP_Composite); 332 NVC0PushProgram(pNv, PFP_CCA, NVE0FP_CAComposite); 333 NVC0PushProgram(pNv, PFP_CCASA, NVE0FP_CACompositeSrcAlpha); 334 NVC0PushProgram(pNv, PFP_S_A8, NVE0FP_Source_A8); 335 NVC0PushProgram(pNv, PFP_C_A8, NVE0FP_Composite_A8); 336 NVC0PushProgram(pNv, PFP_NV12, NVE0FP_NV12); 337 } else { 338 NVC0PushProgram(pNv, PVP_PASS, NVF0VP_Transform2); 339 NVC0PushProgram(pNv, PFP_S, NVF0FP_Source); 340 NVC0PushProgram(pNv, PFP_C, NVF0FP_Composite); 341 NVC0PushProgram(pNv, PFP_CCA, NVF0FP_CAComposite); 342 NVC0PushProgram(pNv, PFP_CCASA, NVF0FP_CACompositeSrcAlpha); 343 NVC0PushProgram(pNv, PFP_S_A8, NVF0FP_Source_A8); 344 NVC0PushProgram(pNv, PFP_C_A8, NVF0FP_Composite_A8); 345 NVC0PushProgram(pNv, PFP_NV12, NVF0FP_NV12); 346 } 347 348 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 4); 349 PUSH_DATA (push, NVC0_3D_SP_SELECT_PROGRAM_VP_B | 350 NVC0_3D_SP_SELECT_ENABLE); 351 PUSH_DATA (push, PVP_PASS); 352 PUSH_DATA (push, 0x00000000); 353 PUSH_DATA (push, 8); 354 BEGIN_NVC0(push, NVC0_3D(VERT_COLOR_CLAMP_EN), 1); 355 PUSH_DATA (push, 1); 356 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 357 PUSH_DATA (push, 256); 358 PUSH_DATA (push, (bo->offset + PVP_DATA) >> 32); 359 PUSH_DATA (push, (bo->offset + PVP_DATA)); 360 BEGIN_NVC0(push, NVC0_3D(CB_BIND(0)), 1); 361 PUSH_DATA (push, 0x01); 362 363 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 4); 364 PUSH_DATA (push, NVC0_3D_SP_SELECT_PROGRAM_FP | 365 NVC0_3D_SP_SELECT_ENABLE); 366 PUSH_DATA (push, PFP_S); 367 PUSH_DATA (push, 0x00000000); 368 PUSH_DATA (push, 8); 369 BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1); 370 PUSH_DATA (push, 0x11111111); 371 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); 372 PUSH_DATA (push, 256); 373 PUSH_DATA (push, (bo->offset + PFP_DATA) >> 32); 374 PUSH_DATA (push, (bo->offset + PFP_DATA)); 375 BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1); 376 PUSH_DATA (push, 0x01); 377 378 return TRUE; 379} 380 381