1 /* 2 * Copyright 2012 Red Hat Inc. 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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 * 24 */ 25 26 #include "util/u_format.h" 27 #include "util/u_math.h" 28 #include "util/u_half.h" 29 30 #include "nv_object.xml.h" 31 #include "nv30/nv30-40_3d.xml.h" 32 #include "nv30/nv30_context.h" 33 #include "nv30/nv30_format.h" 34 35 static void 36 nv30_validate_fb(struct nv30_context *nv30) 37 { 38 struct pipe_screen *pscreen = &nv30->screen->base.base; 39 struct pipe_framebuffer_state *fb = &nv30->framebuffer; 40 struct nouveau_pushbuf *push = nv30->base.pushbuf; 41 struct nouveau_object *eng3d = nv30->screen->eng3d; 42 uint32_t rt_format; 43 int h = fb->height; 44 int w = fb->width; 45 int x = 0; 46 int y = 0; 47 48 nv30->state.rt_enable = (NV30_3D_RT_ENABLE_COLOR0 << fb->nr_cbufs) - 1; 49 if (nv30->state.rt_enable > 1) 50 nv30->state.rt_enable |= NV30_3D_RT_ENABLE_MRT; 51 52 rt_format = 0; 53 if (fb->nr_cbufs > 0) { 54 struct nv30_miptree *mt = nv30_miptree(fb->cbufs[0]->texture); 55 rt_format |= nv30_format(pscreen, fb->cbufs[0]->format)->hw; 56 rt_format |= mt->ms_mode; 57 if (mt->swizzled) 58 rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED; 59 else 60 rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR; 61 } else { 62 if (fb->zsbuf && util_format_get_blocksize(fb->zsbuf->format) > 2) 63 rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8; 64 else 65 rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5; 66 } 67 68 if (fb->zsbuf) { 69 rt_format |= nv30_format(pscreen, fb->zsbuf->format)->hw; 70 if (nv30_miptree(fb->zsbuf->texture)->swizzled) 71 rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED; 72 else 73 rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR; 74 } else { 75 if (fb->nr_cbufs && util_format_get_blocksize(fb->cbufs[0]->format) > 2) 76 rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8; 77 else 78 rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16; 79 } 80 81 /* hardware rounds down render target offset to 64 bytes, but surfaces 82 * with a size of 2x2 pixel (16bpp) or 1x1 pixel (32bpp) have an 83 * unaligned start aaddress. For these two important square formats 84 * we can hack around this limitation by adjusting the viewport origin 85 */ 86 if (nv30->state.rt_enable) { 87 int off = nv30_surface(fb->cbufs[0])->offset & 63; 88 if (off) { 89 x += off / (util_format_get_blocksize(fb->cbufs[0]->format) * 2); 90 w = 16; 91 h = 2; 92 } 93 } 94 95 if (rt_format & NV30_3D_RT_FORMAT_TYPE_SWIZZLED) { 96 rt_format |= util_logbase2(w) << 16; 97 rt_format |= util_logbase2(h) << 24; 98 } 99 100 if (!PUSH_SPACE(push, 64)) 101 return; 102 PUSH_RESET(push, BUFCTX_FB); 103 104 BEGIN_NV04(push, SUBC_3D(0x1da4), 1); 105 PUSH_DATA (push, 0); 106 BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3); 107 PUSH_DATA (push, w << 16); 108 PUSH_DATA (push, h << 16); 109 PUSH_DATA (push, rt_format); 110 BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 4); 111 PUSH_DATA (push, (y << 16) | x); 112 PUSH_DATA (push, 0); 113 PUSH_DATA (push, ((w - 1) << 16) | 0); 114 PUSH_DATA (push, ((h - 1) << 16) | 0); 115 116 if ((nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR0) || fb->zsbuf) { 117 struct nv30_surface *rsf = nv30_surface(fb->cbufs[0]); 118 struct nv30_surface *zsf = nv30_surface(fb->zsbuf); 119 struct nouveau_bo *rbo, *zbo; 120 121 if (!rsf) rsf = zsf; 122 else if (!zsf) zsf = rsf; 123 rbo = nv30_miptree(rsf->base.texture)->base.bo; 124 zbo = nv30_miptree(zsf->base.texture)->base.bo; 125 126 if (eng3d->oclass >= NV40_3D_CLASS) { 127 BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1); 128 PUSH_DATA (push, zsf->pitch); 129 BEGIN_NV04(push, NV40_3D(COLOR0_PITCH), 3); 130 PUSH_DATA (push, rsf->pitch); 131 } else { 132 BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 3); 133 PUSH_DATA (push, (zsf->pitch << 16) | rsf->pitch); 134 } 135 PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), BUFCTX_FB, rbo, rsf->offset & ~63, 136 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 137 PUSH_MTHDl(push, NV30_3D(ZETA_OFFSET), BUFCTX_FB, zbo, zsf->offset & ~63, 138 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 139 } 140 141 if (nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR1) { 142 struct nv30_surface *sf = nv30_surface(fb->cbufs[1]); 143 struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo; 144 145 BEGIN_NV04(push, NV30_3D(COLOR1_OFFSET), 2); 146 PUSH_MTHDl(push, NV30_3D(COLOR1_OFFSET), BUFCTX_FB, bo, sf->offset, 147 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 148 PUSH_DATA (push, sf->pitch); 149 } 150 151 if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR2) { 152 struct nv30_surface *sf = nv30_surface(fb->cbufs[2]); 153 struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo; 154 155 BEGIN_NV04(push, NV40_3D(COLOR2_OFFSET), 1); 156 PUSH_MTHDl(push, NV40_3D(COLOR2_OFFSET), BUFCTX_FB, bo, sf->offset, 157 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 158 BEGIN_NV04(push, NV40_3D(COLOR2_PITCH), 1); 159 PUSH_DATA (push, sf->pitch); 160 } 161 162 if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR3) { 163 struct nv30_surface *sf = nv30_surface(fb->cbufs[3]); 164 struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo; 165 166 BEGIN_NV04(push, NV40_3D(COLOR3_OFFSET), 1); 167 PUSH_MTHDl(push, NV40_3D(COLOR3_OFFSET), BUFCTX_FB, bo, sf->offset, 168 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 169 BEGIN_NV04(push, NV40_3D(COLOR3_PITCH), 1); 170 PUSH_DATA (push, sf->pitch); 171 } 172 } 173 174 static void 175 nv30_validate_blend_colour(struct nv30_context *nv30) 176 { 177 struct nouveau_pushbuf *push = nv30->base.pushbuf; 178 float *rgba = nv30->blend_colour.color; 179 180 if (nv30->framebuffer.nr_cbufs) { 181 switch (nv30->framebuffer.cbufs[0]->format) { 182 case PIPE_FORMAT_R16G16B16A16_FLOAT: 183 case PIPE_FORMAT_R32G32B32A32_FLOAT: 184 BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1); 185 PUSH_DATA (push, (util_float_to_half(rgba[0]) << 0) | 186 (util_float_to_half(rgba[1]) << 16)); 187 BEGIN_NV04(push, SUBC_3D(0x037c), 1); 188 PUSH_DATA (push, (util_float_to_half(rgba[2]) << 0) | 189 (util_float_to_half(rgba[3]) << 16)); 190 break; 191 default: 192 break; 193 } 194 } 195 196 BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1); 197 PUSH_DATA (push, (float_to_ubyte(rgba[3]) << 24) | 198 (float_to_ubyte(rgba[0]) << 16) | 199 (float_to_ubyte(rgba[1]) << 8) | 200 (float_to_ubyte(rgba[2]) << 0)); 201 } 202 203 static void 204 nv30_validate_stencil_ref(struct nv30_context *nv30) 205 { 206 struct nouveau_pushbuf *push = nv30->base.pushbuf; 207 208 BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(0)), 1); 209 PUSH_DATA (push, nv30->stencil_ref.ref_value[0]); 210 BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(1)), 1); 211 PUSH_DATA (push, nv30->stencil_ref.ref_value[1]); 212 } 213 214 static void 215 nv30_validate_stipple(struct nv30_context *nv30) 216 { 217 struct nouveau_pushbuf *push = nv30->base.pushbuf; 218 219 BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 32); 220 PUSH_DATAp(push, nv30->stipple.stipple, 32); 221 } 222 223 static void 224 nv30_validate_scissor(struct nv30_context *nv30) 225 { 226 struct nouveau_pushbuf *push = nv30->base.pushbuf; 227 struct pipe_scissor_state *s = &nv30->scissor; 228 bool rast_scissor = nv30->rast ? nv30->rast->pipe.scissor : false; 229 230 if (!(nv30->dirty & NV30_NEW_SCISSOR) && 231 rast_scissor != nv30->state.scissor_off) 232 return; 233 nv30->state.scissor_off = !rast_scissor; 234 235 BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); 236 if (rast_scissor) { 237 PUSH_DATA (push, ((s->maxx - s->minx) << 16) | s->minx); 238 PUSH_DATA (push, ((s->maxy - s->miny) << 16) | s->miny); 239 } else { 240 PUSH_DATA (push, 0x10000000); 241 PUSH_DATA (push, 0x10000000); 242 } 243 } 244 245 static void 246 nv30_validate_viewport(struct nv30_context *nv30) 247 { 248 struct nouveau_pushbuf *push = nv30->base.pushbuf; 249 struct pipe_viewport_state *vp = &nv30->viewport; 250 251 unsigned x = CLAMP(vp->translate[0] - fabsf(vp->scale[0]), 0, 4095); 252 unsigned y = CLAMP(vp->translate[1] - fabsf(vp->scale[1]), 0, 4095); 253 unsigned w = CLAMP(2.0f * fabsf(vp->scale[0]), 0, 4096); 254 unsigned h = CLAMP(2.0f * fabsf(vp->scale[1]), 0, 4096); 255 256 BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8); 257 PUSH_DATAf(push, vp->translate[0]); 258 PUSH_DATAf(push, vp->translate[1]); 259 PUSH_DATAf(push, vp->translate[2]); 260 PUSH_DATAf(push, 0.0f); 261 PUSH_DATAf(push, vp->scale[0]); 262 PUSH_DATAf(push, vp->scale[1]); 263 PUSH_DATAf(push, vp->scale[2]); 264 PUSH_DATAf(push, 0.0f); 265 BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2); 266 PUSH_DATAf(push, vp->translate[2] - fabsf(vp->scale[2])); 267 PUSH_DATAf(push, vp->translate[2] + fabsf(vp->scale[2])); 268 269 BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2); 270 PUSH_DATA (push, (w << 16) | x); 271 PUSH_DATA (push, (h << 16) | y); 272 } 273 274 static void 275 nv30_validate_clip(struct nv30_context *nv30) 276 { 277 struct nouveau_pushbuf *push = nv30->base.pushbuf; 278 unsigned i; 279 uint32_t clpd_enable = 0; 280 281 for (i = 0; i < 6; i++) { 282 if (nv30->dirty & NV30_NEW_CLIP) { 283 BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5); 284 PUSH_DATA (push, i); 285 PUSH_DATAp(push, nv30->clip.ucp[i], 4); 286 } 287 if (nv30->rast->pipe.clip_plane_enable & (1 << i)) 288 clpd_enable |= 2 << (4*i); 289 } 290 291 BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1); 292 PUSH_DATA (push, clpd_enable); 293 } 294 295 static void 296 nv30_validate_blend(struct nv30_context *nv30) 297 { 298 struct nouveau_pushbuf *push = nv30->base.pushbuf; 299 300 PUSH_SPACE(push, nv30->blend->size); 301 PUSH_DATAp(push, nv30->blend->data, nv30->blend->size); 302 } 303 304 static void 305 nv30_validate_zsa(struct nv30_context *nv30) 306 { 307 struct nouveau_pushbuf *push = nv30->base.pushbuf; 308 309 PUSH_SPACE(push, nv30->zsa->size); 310 PUSH_DATAp(push, nv30->zsa->data, nv30->zsa->size); 311 } 312 313 static void 314 nv30_validate_rasterizer(struct nv30_context *nv30) 315 { 316 struct nouveau_pushbuf *push = nv30->base.pushbuf; 317 318 PUSH_SPACE(push, nv30->rast->size); 319 PUSH_DATAp(push, nv30->rast->data, nv30->rast->size); 320 } 321 322 static void 323 nv30_validate_multisample(struct nv30_context *nv30) 324 { 325 struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe; 326 struct pipe_blend_state *blend = &nv30->blend->pipe; 327 struct nouveau_pushbuf *push = nv30->base.pushbuf; 328 uint32_t ctrl = nv30->sample_mask << 16; 329 330 if (blend->alpha_to_one) 331 ctrl |= 0x00000100; 332 if (blend->alpha_to_coverage) 333 ctrl |= 0x00000010; 334 if (rasterizer->multisample) 335 ctrl |= 0x00000001; 336 337 BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1); 338 PUSH_DATA (push, ctrl); 339 } 340 341 static void 342 nv30_validate_fragment(struct nv30_context *nv30) 343 { 344 struct nouveau_pushbuf *push = nv30->base.pushbuf; 345 struct nv30_fragprog *fp = nv30->fragprog.program; 346 347 BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1); 348 PUSH_DATA (push, nv30->state.rt_enable & (fp ? ~fp->rt_enable : 0x1f)); 349 BEGIN_NV04(push, NV30_3D(COORD_CONVENTIONS), 1); 350 PUSH_DATA (push, (fp ? fp->coord_conventions : 0) | nv30->framebuffer.height); 351 } 352 353 static void 354 nv30_validate_point_coord(struct nv30_context *nv30) 355 { 356 struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe; 357 struct nouveau_pushbuf *push = nv30->base.pushbuf; 358 struct nv30_fragprog *fp = nv30->fragprog.program; 359 uint32_t hw = 0x00000000; 360 361 if (rasterizer) { 362 hw |= (nv30->rast->pipe.sprite_coord_enable & 0xff) << 8; 363 if (fp) 364 hw |= fp->point_sprite_control; 365 366 if (rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) { 367 if (hw) 368 nv30->draw_flags |= NV30_NEW_RASTERIZER; 369 } else 370 if (rasterizer->point_quad_rasterization) { 371 hw |= NV30_3D_POINT_SPRITE_ENABLE; 372 } 373 } 374 375 BEGIN_NV04(push, NV30_3D(POINT_SPRITE), 1); 376 PUSH_DATA (push, hw); 377 } 378 379 struct state_validate { 380 void (*func)(struct nv30_context *); 381 uint32_t mask; 382 }; 383 384 static struct state_validate hwtnl_validate_list[] = { 385 { nv30_validate_fb, NV30_NEW_FRAMEBUFFER }, 386 { nv30_validate_blend, NV30_NEW_BLEND }, 387 { nv30_validate_zsa, NV30_NEW_ZSA }, 388 { nv30_validate_rasterizer, NV30_NEW_RASTERIZER }, 389 { nv30_validate_multisample, NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND | 390 NV30_NEW_RASTERIZER }, 391 { nv30_validate_blend_colour, NV30_NEW_BLEND_COLOUR | 392 NV30_NEW_FRAMEBUFFER }, 393 { nv30_validate_stencil_ref, NV30_NEW_STENCIL_REF }, 394 { nv30_validate_stipple, NV30_NEW_STIPPLE }, 395 { nv30_validate_scissor, NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER }, 396 { nv30_validate_viewport, NV30_NEW_VIEWPORT }, 397 { nv30_validate_clip, NV30_NEW_CLIP | NV30_NEW_RASTERIZER }, 398 { nv30_fragprog_validate, NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST }, 399 { nv30_vertprog_validate, NV30_NEW_VERTPROG | NV30_NEW_VERTCONST | 400 NV30_NEW_FRAGPROG | NV30_NEW_RASTERIZER }, 401 { nv30_validate_fragment, NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG }, 402 { nv30_validate_point_coord, NV30_NEW_RASTERIZER | NV30_NEW_FRAGPROG }, 403 { nv30_fragtex_validate, NV30_NEW_FRAGTEX }, 404 { nv40_verttex_validate, NV30_NEW_VERTTEX }, 405 { nv30_vbo_validate, NV30_NEW_VERTEX | NV30_NEW_ARRAYS }, 406 {} 407 }; 408 409 #define NV30_SWTNL_MASK (NV30_NEW_VIEWPORT | \ 410 NV30_NEW_CLIP | \ 411 NV30_NEW_VERTPROG | \ 412 NV30_NEW_VERTCONST | \ 413 NV30_NEW_VERTTEX | \ 414 NV30_NEW_VERTEX | \ 415 NV30_NEW_ARRAYS) 416 417 static struct state_validate swtnl_validate_list[] = { 418 { nv30_validate_fb, NV30_NEW_FRAMEBUFFER }, 419 { nv30_validate_blend, NV30_NEW_BLEND }, 420 { nv30_validate_zsa, NV30_NEW_ZSA }, 421 { nv30_validate_rasterizer, NV30_NEW_RASTERIZER }, 422 { nv30_validate_multisample, NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND | 423 NV30_NEW_RASTERIZER }, 424 { nv30_validate_blend_colour, NV30_NEW_BLEND_COLOUR | 425 NV30_NEW_FRAMEBUFFER }, 426 { nv30_validate_stencil_ref, NV30_NEW_STENCIL_REF }, 427 { nv30_validate_stipple, NV30_NEW_STIPPLE }, 428 { nv30_validate_scissor, NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER }, 429 { nv30_fragprog_validate, NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST }, 430 { nv30_validate_fragment, NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG }, 431 { nv30_fragtex_validate, NV30_NEW_FRAGTEX }, 432 {} 433 }; 434 435 static void 436 nv30_state_context_switch(struct nv30_context *nv30) 437 { 438 struct nv30_context *prev = nv30->screen->cur_ctx; 439 440 if (prev) 441 nv30->state = prev->state; 442 nv30->dirty = NV30_NEW_ALL; 443 444 if (!nv30->vertex) 445 nv30->dirty &= ~(NV30_NEW_VERTEX | NV30_NEW_ARRAYS); 446 447 if (!nv30->vertprog.program) 448 nv30->dirty &= ~NV30_NEW_VERTPROG; 449 if (!nv30->fragprog.program) 450 nv30->dirty &= ~NV30_NEW_FRAGPROG; 451 452 if (!nv30->blend) 453 nv30->dirty &= ~NV30_NEW_BLEND; 454 if (!nv30->rast) 455 nv30->dirty &= ~NV30_NEW_RASTERIZER; 456 if (!nv30->zsa) 457 nv30->dirty &= ~NV30_NEW_ZSA; 458 459 nv30->screen->cur_ctx = nv30; 460 nv30->base.pushbuf->user_priv = &nv30->bufctx; 461 } 462 463 bool 464 nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl) 465 { 466 struct nouveau_screen *screen = &nv30->screen->base; 467 struct nouveau_pushbuf *push = nv30->base.pushbuf; 468 struct nouveau_bufctx *bctx = nv30->bufctx; 469 struct nouveau_bufref *bref; 470 struct state_validate *validate; 471 472 if (nv30->screen->cur_ctx != nv30) 473 nv30_state_context_switch(nv30); 474 475 if (hwtnl) { 476 nv30->draw_dirty |= nv30->dirty; 477 if (nv30->draw_flags) { 478 nv30->draw_flags &= ~nv30->dirty; 479 if (!nv30->draw_flags) 480 nv30->dirty |= NV30_SWTNL_MASK; 481 } 482 } 483 484 if (!nv30->draw_flags) 485 validate = hwtnl_validate_list; 486 else 487 validate = swtnl_validate_list; 488 489 mask &= nv30->dirty; 490 491 if (mask) { 492 while (validate->func) { 493 if (mask & validate->mask) 494 validate->func(nv30); 495 validate++; 496 } 497 498 nv30->dirty &= ~mask; 499 } 500 501 nouveau_pushbuf_bufctx(push, bctx); 502 if (nouveau_pushbuf_validate(push)) { 503 nouveau_pushbuf_bufctx(push, NULL); 504 return false; 505 } 506 507 /*XXX*/ 508 BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1); 509 PUSH_DATA (push, 0); 510 if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) { 511 BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); 512 PUSH_DATA (push, 2); 513 BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); 514 PUSH_DATA (push, 1); 515 BEGIN_NV04(push, NV30_3D(R1718), 1); 516 PUSH_DATA (push, 0); 517 BEGIN_NV04(push, NV30_3D(R1718), 1); 518 PUSH_DATA (push, 0); 519 BEGIN_NV04(push, NV30_3D(R1718), 1); 520 PUSH_DATA (push, 0); 521 } 522 523 LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) { 524 struct nv04_resource *res = bref->priv; 525 if (res && res->mm) { 526 nouveau_fence_ref(screen->fence.current, &res->fence); 527 528 if (bref->flags & NOUVEAU_BO_RD) 529 res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; 530 531 if (bref->flags & NOUVEAU_BO_WR) { 532 nouveau_fence_ref(screen->fence.current, &res->fence_wr); 533 res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; 534 } 535 } 536 } 537 538 return true; 539 } 540 541 void 542 nv30_state_release(struct nv30_context *nv30) 543 { 544 nouveau_pushbuf_bufctx(nv30->base.pushbuf, NULL); 545 } 546