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 <stdint.h> 24 25 #include "pipe/p_defines.h" 26 27 #include "util/u_inlines.h" 28 #include "util/u_pack_color.h" 29 #include "util/u_format.h" 30 #include "util/u_surface.h" 31 32 #include "nvc0_context.h" 33 #include "nvc0_resource.h" 34 35 #include "nv50/nv50_defs.xml.h" 36 #include "nv50/nv50_texture.xml.h" 37 38 #define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL 39 40 /* return TRUE for formats that can be converted among each other by NVC0_2D */ 41 static INLINE boolean 42 nvc0_2d_format_faithful(enum pipe_format format) 43 { 44 uint8_t id = nvc0_format_table[format].rt; 45 46 return (id >= 0xc0) && (NVC0_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))); 47 } 48 49 static INLINE uint8_t 50 nvc0_2d_format(enum pipe_format format) 51 { 52 uint8_t id = nvc0_format_table[format].rt; 53 54 /* Hardware values for color formats range from 0xc0 to 0xff, 55 * but the 2D engine doesn't support all of them. 56 */ 57 if (nvc0_2d_format_faithful(format)) 58 return id; 59 60 switch (util_format_get_blocksize(format)) { 61 case 1: 62 return NV50_SURFACE_FORMAT_R8_UNORM; 63 case 2: 64 return NV50_SURFACE_FORMAT_R16_UNORM; 65 case 4: 66 return NV50_SURFACE_FORMAT_BGRA8_UNORM; 67 case 8: 68 return NV50_SURFACE_FORMAT_RGBA16_UNORM; 69 case 16: 70 return NV50_SURFACE_FORMAT_RGBA32_FLOAT; 71 default: 72 return 0; 73 } 74 } 75 76 static int 77 nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst, 78 struct nv50_miptree *mt, unsigned level, unsigned layer) 79 { 80 struct nouveau_bo *bo = mt->base.bo; 81 uint32_t width, height, depth; 82 uint32_t format; 83 uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT; 84 uint32_t offset = mt->level[level].offset; 85 86 format = nvc0_2d_format(mt->base.base.format); 87 if (!format) { 88 NOUVEAU_ERR("invalid/unsupported surface format: %s\n", 89 util_format_name(mt->base.base.format)); 90 return 1; 91 } 92 93 width = u_minify(mt->base.base.width0, level) << mt->ms_x; 94 height = u_minify(mt->base.base.height0, level) << mt->ms_y; 95 depth = u_minify(mt->base.base.depth0, level); 96 97 /* layer has to be < depth, and depth > tile depth / 2 */ 98 99 if (!mt->layout_3d) { 100 offset += mt->layer_stride * layer; 101 layer = 0; 102 depth = 1; 103 } else 104 if (!dst) { 105 offset += nvc0_mt_zslice_offset(mt, level, layer); 106 layer = 0; 107 } 108 109 if (nouveau_bo_memtype(bo)) { 110 BEGIN_NVC0(push, SUBC_2D(mthd), 2); 111 PUSH_DATA (push, format); 112 PUSH_DATA (push, 1); 113 BEGIN_NVC0(push, SUBC_2D(mthd + 0x14), 5); 114 PUSH_DATA (push, mt->level[level].pitch); 115 PUSH_DATA (push, width); 116 PUSH_DATA (push, height); 117 PUSH_DATAh(push, bo->offset + offset); 118 PUSH_DATA (push, bo->offset + offset); 119 } else { 120 BEGIN_NVC0(push, SUBC_2D(mthd), 5); 121 PUSH_DATA (push, format); 122 PUSH_DATA (push, 0); 123 PUSH_DATA (push, mt->level[level].tile_mode); 124 PUSH_DATA (push, depth); 125 PUSH_DATA (push, layer); 126 BEGIN_NVC0(push, SUBC_2D(mthd + 0x18), 4); 127 PUSH_DATA (push, width); 128 PUSH_DATA (push, height); 129 PUSH_DATAh(push, bo->offset + offset); 130 PUSH_DATA (push, bo->offset + offset); 131 } 132 133 #if 0 134 if (dst) { 135 BEGIN_NVC0(push, SUBC_2D(NVC0_2D_CLIP_X), 4); 136 PUSH_DATA (push, 0); 137 PUSH_DATA (push, 0); 138 PUSH_DATA (push, width); 139 PUSH_DATA (push, height); 140 } 141 #endif 142 return 0; 143 } 144 145 static int 146 nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push, 147 struct nv50_miptree *dst, unsigned dst_level, 148 unsigned dx, unsigned dy, unsigned dz, 149 struct nv50_miptree *src, unsigned src_level, 150 unsigned sx, unsigned sy, unsigned sz, 151 unsigned w, unsigned h) 152 { 153 static const uint32_t duvdxy[5] = 154 { 155 0x40000000, 0x80000000, 0x00000001, 0x00000002, 0x00000004 156 }; 157 158 int ret; 159 uint32_t ctrl = 0x00; 160 161 ret = PUSH_SPACE(push, 2 * 16 + 32); 162 if (ret) 163 return ret; 164 165 ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz); 166 if (ret) 167 return ret; 168 169 ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz); 170 if (ret) 171 return ret; 172 173 /* NOTE: 2D engine doesn't work for MS8 */ 174 if (src->ms_x) 175 ctrl = 0x11; 176 177 /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */ 178 BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1); 179 PUSH_DATA (push, ctrl); 180 BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4); 181 PUSH_DATA (push, dx << dst->ms_x); 182 PUSH_DATA (push, dy << dst->ms_y); 183 PUSH_DATA (push, w << dst->ms_x); 184 PUSH_DATA (push, h << dst->ms_y); 185 BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4); 186 PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); 187 PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); 188 PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); 189 PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); 190 BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4); 191 PUSH_DATA (push, 0); 192 PUSH_DATA (push, sx << src->ms_x); 193 PUSH_DATA (push, 0); 194 PUSH_DATA (push, sy << src->ms_x); 195 196 return 0; 197 } 198 199 static void 200 nvc0_resource_copy_region(struct pipe_context *pipe, 201 struct pipe_resource *dst, unsigned dst_level, 202 unsigned dstx, unsigned dsty, unsigned dstz, 203 struct pipe_resource *src, unsigned src_level, 204 const struct pipe_box *src_box) 205 { 206 struct nvc0_context *nvc0 = nvc0_context(pipe); 207 int ret; 208 boolean m2mf; 209 unsigned dst_layer = dstz, src_layer = src_box->z; 210 211 /* Fallback for buffers. */ 212 if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 213 util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 214 src, src_level, src_box); 215 return; 216 } 217 218 /* 0 and 1 are equal, only supporting 0/1, 2, 4 and 8 */ 219 assert((src->nr_samples | 1) == (dst->nr_samples | 1)); 220 221 m2mf = (src->format == dst->format) || 222 (util_format_get_blocksizebits(src->format) == 223 util_format_get_blocksizebits(dst->format)); 224 225 nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; 226 227 if (m2mf) { 228 struct nv50_m2mf_rect drect, srect; 229 unsigned i; 230 unsigned nx = util_format_get_nblocksx(src->format, src_box->width); 231 unsigned ny = util_format_get_nblocksy(src->format, src_box->height); 232 233 nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz); 234 nv50_m2mf_rect_setup(&srect, src, src_level, 235 src_box->x, src_box->y, src_box->z); 236 237 for (i = 0; i < src_box->depth; ++i) { 238 nvc0->m2mf_copy_rect(nvc0, &drect, &srect, nx, ny); 239 240 if (nv50_miptree(dst)->layout_3d) 241 drect.z++; 242 else 243 drect.base += nv50_miptree(dst)->layer_stride; 244 245 if (nv50_miptree(src)->layout_3d) 246 srect.z++; 247 else 248 srect.base += nv50_miptree(src)->layer_stride; 249 } 250 return; 251 } 252 253 assert(nvc0_2d_format_faithful(src->format)); 254 assert(nvc0_2d_format_faithful(dst->format)); 255 256 BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD); 257 BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR); 258 nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx); 259 nouveau_pushbuf_validate(nvc0->base.pushbuf); 260 261 for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) { 262 ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf, 263 nv50_miptree(dst), dst_level, 264 dstx, dsty, dst_layer, 265 nv50_miptree(src), src_level, 266 src_box->x, src_box->y, src_layer, 267 src_box->width, src_box->height); 268 if (ret) 269 break; 270 } 271 nouveau_bufctx_reset(nvc0->bufctx, 0); 272 } 273 274 static void 275 nvc0_clear_render_target(struct pipe_context *pipe, 276 struct pipe_surface *dst, 277 const union pipe_color_union *color, 278 unsigned dstx, unsigned dsty, 279 unsigned width, unsigned height) 280 { 281 struct nvc0_context *nvc0 = nvc0_context(pipe); 282 struct nouveau_pushbuf *push = nvc0->base.pushbuf; 283 struct nv50_surface *sf = nv50_surface(dst); 284 struct nv04_resource *res = nv04_resource(sf->base.texture); 285 unsigned z; 286 287 BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); 288 PUSH_DATAf(push, color->f[0]); 289 PUSH_DATAf(push, color->f[1]); 290 PUSH_DATAf(push, color->f[2]); 291 PUSH_DATAf(push, color->f[3]); 292 293 BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 294 PUSH_DATA (push, ( width << 16) | dstx); 295 PUSH_DATA (push, (height << 16) | dsty); 296 297 BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); 298 PUSH_DATA (push, 1); 299 BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9); 300 PUSH_DATAh(push, res->address + sf->offset); 301 PUSH_DATA (push, res->address + sf->offset); 302 if (likely(nouveau_bo_memtype(res->bo))) { 303 struct nv50_miptree *mt = nv50_miptree(dst->texture); 304 305 PUSH_DATA(push, sf->width); 306 PUSH_DATA(push, sf->height); 307 PUSH_DATA(push, nvc0_format_table[dst->format].rt); 308 PUSH_DATA(push, (mt->layout_3d << 16) | 309 mt->level[sf->base.u.tex.level].tile_mode); 310 PUSH_DATA(push, dst->u.tex.first_layer + sf->depth); 311 PUSH_DATA(push, mt->layer_stride >> 2); 312 PUSH_DATA(push, dst->u.tex.first_layer); 313 } else { 314 if (res->base.target == PIPE_BUFFER) { 315 PUSH_DATA(push, 262144); 316 PUSH_DATA(push, 1); 317 } else { 318 PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch); 319 PUSH_DATA(push, sf->height); 320 } 321 PUSH_DATA(push, nvc0_format_table[sf->base.format].rt); 322 PUSH_DATA(push, 1 << 12); 323 PUSH_DATA(push, 1); 324 PUSH_DATA(push, 0); 325 PUSH_DATA(push, 0); 326 327 IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); 328 329 /* tiled textures don't have to be fenced, they're not mapped directly */ 330 nvc0_resource_fence(res, NOUVEAU_BO_WR); 331 } 332 333 for (z = 0; z < sf->depth; ++z) { 334 BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 335 PUSH_DATA (push, 0x3c | 336 (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 337 } 338 339 nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; 340 } 341 342 static void 343 nvc0_clear_depth_stencil(struct pipe_context *pipe, 344 struct pipe_surface *dst, 345 unsigned clear_flags, 346 double depth, 347 unsigned stencil, 348 unsigned dstx, unsigned dsty, 349 unsigned width, unsigned height) 350 { 351 struct nvc0_context *nvc0 = nvc0_context(pipe); 352 struct nouveau_pushbuf *push = nvc0->base.pushbuf; 353 struct nv50_miptree *mt = nv50_miptree(dst->texture); 354 struct nv50_surface *sf = nv50_surface(dst); 355 uint32_t mode = 0; 356 int unk = mt->base.base.target == PIPE_TEXTURE_2D; 357 unsigned z; 358 359 if (clear_flags & PIPE_CLEAR_DEPTH) { 360 BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1); 361 PUSH_DATAf(push, depth); 362 mode |= NVC0_3D_CLEAR_BUFFERS_Z; 363 } 364 365 if (clear_flags & PIPE_CLEAR_STENCIL) { 366 BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1); 367 PUSH_DATA (push, stencil & 0xff); 368 mode |= NVC0_3D_CLEAR_BUFFERS_S; 369 } 370 371 BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 372 PUSH_DATA (push, ( width << 16) | dstx); 373 PUSH_DATA (push, (height << 16) | dsty); 374 375 BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5); 376 PUSH_DATAh(push, mt->base.address + sf->offset); 377 PUSH_DATA (push, mt->base.address + sf->offset); 378 PUSH_DATA (push, nvc0_format_table[dst->format].rt); 379 PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); 380 PUSH_DATA (push, mt->layer_stride >> 2); 381 BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); 382 PUSH_DATA (push, 1); 383 BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3); 384 PUSH_DATA (push, sf->width); 385 PUSH_DATA (push, sf->height); 386 PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth)); 387 BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1); 388 PUSH_DATA (push, dst->u.tex.first_layer); 389 390 for (z = 0; z < sf->depth; ++z) { 391 BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 392 PUSH_DATA (push, mode | 393 (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 394 } 395 396 nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; 397 } 398 399 void 400 nvc0_clear(struct pipe_context *pipe, unsigned buffers, 401 const union pipe_color_union *color, 402 double depth, unsigned stencil) 403 { 404 struct nvc0_context *nvc0 = nvc0_context(pipe); 405 struct nouveau_pushbuf *push = nvc0->base.pushbuf; 406 struct pipe_framebuffer_state *fb = &nvc0->framebuffer; 407 unsigned i; 408 uint32_t mode = 0; 409 410 /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */ 411 if (!nvc0_state_validate(nvc0, NVC0_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2))) 412 return; 413 414 if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { 415 BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); 416 PUSH_DATAf(push, color->f[0]); 417 PUSH_DATAf(push, color->f[1]); 418 PUSH_DATAf(push, color->f[2]); 419 PUSH_DATAf(push, color->f[3]); 420 mode = 421 NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G | 422 NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A; 423 } 424 425 if (buffers & PIPE_CLEAR_DEPTH) { 426 BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1); 427 PUSH_DATA (push, fui(depth)); 428 mode |= NVC0_3D_CLEAR_BUFFERS_Z; 429 } 430 431 if (buffers & PIPE_CLEAR_STENCIL) { 432 BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1); 433 PUSH_DATA (push, stencil & 0xff); 434 mode |= NVC0_3D_CLEAR_BUFFERS_S; 435 } 436 437 BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 438 PUSH_DATA (push, mode); 439 440 for (i = 1; i < fb->nr_cbufs; i++) { 441 BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 442 PUSH_DATA (push, (i << 6) | 0x3c); 443 } 444 } 445 446 447 struct nvc0_blitctx 448 { 449 struct nvc0_screen *screen; 450 struct { 451 struct pipe_framebuffer_state fb; 452 struct nvc0_program *vp; 453 struct nvc0_program *tcp; 454 struct nvc0_program *tep; 455 struct nvc0_program *gp; 456 struct nvc0_program *fp; 457 unsigned num_textures[5]; 458 unsigned num_samplers[5]; 459 struct pipe_sampler_view *texture[2]; 460 struct nv50_tsc_entry *sampler[2]; 461 unsigned dirty; 462 } saved; 463 struct nvc0_program vp; 464 struct nvc0_program fp; 465 struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */ 466 uint32_t fp_offset; 467 uint16_t color_mask; 468 uint8_t filter; 469 }; 470 471 static void 472 nvc0_blitctx_make_vp(struct nvc0_blitctx *blit) 473 { 474 static const uint32_t code[] = 475 { 476 0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */ 477 0xfff11c26, 0x06000090, /* vfetch b64 { $r4 $r5 } a[0x90]*/ 478 0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */ 479 0x13f01c26, 0x0a7e0080, /* export b64 o[0x80] { $r4 $r5 } */ 480 0x00001de7, 0x80000000, /* exit */ 481 }; 482 483 blit->vp.type = PIPE_SHADER_VERTEX; 484 blit->vp.translated = TRUE; 485 blit->vp.code = (uint32_t *)code; /* no relocations -> no modification */ 486 blit->vp.code_size = sizeof(code); 487 blit->vp.max_gpr = 6; 488 blit->vp.vp.edgeflag = PIPE_MAX_ATTRIBS; 489 490 blit->vp.hdr[0] = 0x00020461; /* vertprog magic */ 491 blit->vp.hdr[4] = 0x000ff000; /* no outputs read */ 492 blit->vp.hdr[6] = 0x0000003f; /* a[0x80], a[0x90] */ 493 blit->vp.hdr[13] = 0x0003f000; /* o[0x70], o[0x80] */ 494 } 495 496 static void 497 nvc0_blitctx_make_fp(struct nvc0_blitctx *blit) 498 { 499 static const uint32_t code_nvc0[] = /* use nvc0dis */ 500 { 501 /* 2 coords RGBA in, RGBA out, also for Z32_FLOAT(_S8X24_UINT) 502 * NOTE: 503 * NVC0 doesn't like tex 3d on non-3d textures, but there should 504 * only be 2d and 2d-array MS resources anyway. 505 */ 506 0xfff01c00, 0xc07e0080, 507 0xfff05c00, 0xc07e0084, 508 0x00001e86, 0x8013c000, 509 0x00001de7, 0x80000000, 510 /* size: 0x70 + padding */ 511 0, 0, 0, 0, 512 513 /* 2 coords ZS in, S encoded in R, Z encoded in GBA (8_UNORM) 514 * Setup float outputs in a way that conversion to UNORM yields the 515 * desired byte value. 516 */ 517 /* NOTE: need to repeat header */ 518 0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 519 0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000, 520 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 521 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000, 522 0xfff09c00, 0xc07e0080, 523 0xfff0dc00, 0xc07e0084, 524 0x00201e86, 0x80104000, 525 0x00205f06, 0x80104101, 526 0xfc009c02, 0x312dffff, 527 0x05001c88, 528 0x09009e88, 529 0x04001c02, 0x30ee0202, 530 0xfc205c02, 0x38000003, 531 0x0020dc02, 0x3803fc00, 532 0x00209c02, 0x380003fc, 533 0x05005c88, 534 0x0d00dc88, 535 0x09209e04, 0x18000000, 536 0x04105c02, 0x30ee0202, 537 0x0430dc02, 0x30ce0202, 538 0x04209c02, 0x30de0202, 539 0x00001de7, 0x80000000, 540 /* size: 0xd0 + padding */ 541 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 542 543 /* 2 coords ZS in, Z encoded in RGB, S encoded in A (U8_UNORM) */ 544 0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 545 0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000, 546 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 547 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000, 548 0xfff09c00, 0xc07e0080, 549 0xfff0dc00, 0xc07e0084, 550 0x00201e86, 0x80104000, 551 0x00205f06, 0x80104101, 552 0xfc009c02, 0x312dffff, 553 0x0500dc88, 554 0x09009e88, 555 0x0430dc02, 0x30ee0202, 556 0xfc201c02, 0x38000003, 557 0x00205c02, 0x380003fc, 558 0x00209c02, 0x3803fc00, 559 0x01001c88, 560 0x05005c88, 561 0x09209e04, 0x18000000, 562 0x04001c02, 0x30ee0202, 563 0x04105c02, 0x30de0202, 564 0x04209c02, 0x30ce0202, 565 0x00001de7, 0x80000000, 566 }; 567 static const uint32_t code_nve4[] = /* use nvc0dis */ 568 { 569 /* 2 coords RGBA in, RGBA out, also for Z32_FLOAT(_S8X24_UINT) 570 * NOTE: 571 * NVC0 doesn't like tex 3d on non-3d textures, but there should 572 * only be 2d and 2d-array MS resources anyway. 573 */ 574 0x2202e237, 0x200002ec, 575 0xfff01c00, 0xc07e0080, 576 0xfff05c00, 0xc07e0084, 577 0x00001e86, 0x8013c000, 578 0x00001de6, 0xf0000000, 579 0x00001de7, 0x80000000, 580 /* size: 0x80 */ 581 582 /* 2 coords ZS in, S encoded in R, Z encoded in GBA (8_UNORM) 583 * Setup float outputs in a way that conversion to UNORM yields the 584 * desired byte value. 585 */ 586 /* NOTE: need to repeat header */ 587 0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 588 0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000, 589 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 590 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000, 591 0x0202e237, 0x22804c22, 592 0xfff09c00, 0xc07e0080, 593 0xfff0dc00, 0xc07e0084, 594 0x00201e86, 0x80104008, 595 0x00205f06, 0x80104009, 596 0x00001de6, 0xf0000000, 597 0xfc009c02, 0x312dffff, 598 0x05201e04, 0x18000000, 599 0x00428047, 0x22020272, 600 0x09209c84, 0x14000000, 601 0x04001c02, 0x30ee0202, 602 0xfc205c02, 0x38000003, 603 0x0020dc02, 0x3803fc00, 604 0x00209c02, 0x380003fc, 605 0x05205e04, 0x18000000, 606 0x0d20de04, 0x18000000, 607 0x42004277, 0x200002e0, 608 0x09209e04, 0x18000000, 609 0x04105c02, 0x30ee0202, 610 0x0430dc02, 0x30ce0202, 611 0x04209c02, 0x30de0202, 612 0x00001de7, 0x80000000, 613 /* size: 0x100 */ 614 615 /* 2 coords ZS in, Z encoded in RGB, S encoded in A (U8_UNORM) */ 616 0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 617 0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000, 618 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 619 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000, 620 0x0202e237, 0x22804c22, 621 0xfff09c00, 0xc07e0080, 622 0xfff0dc00, 0xc07e0084, 623 0x00201e86, 0x80104008, 624 0x00205f06, 0x80104009, 625 0x00001de6, 0xf0000000, 626 0xfc009c02, 0x312dffff, 627 0x0520de04, 0x18000000, 628 0x00428047, 0x22020272, 629 0x09209c84, 0x14000000, 630 0x0430dc02, 0x30ee0202, 631 0xfc201c02, 0x38000003, 632 0x00205c02, 0x380003fc, 633 0x00209c02, 0x3803fc00, 634 0x01201e04, 0x18000000, 635 0x05205e04, 0x18000000, 636 0x42004277, 0x200002e0, 637 0x09209e04, 0x18000000, 638 0x04001c02, 0x30ee0202, 639 0x04105c02, 0x30de0202, 640 0x04209c02, 0x30ce0202, 641 0x00001de7, 0x80000000, 642 }; 643 644 blit->fp.type = PIPE_SHADER_FRAGMENT; 645 blit->fp.translated = TRUE; 646 if (blit->screen->base.class_3d >= NVE4_3D_CLASS) { 647 blit->fp.code = (uint32_t *)code_nve4; /* const_cast */ 648 blit->fp.code_size = sizeof(code_nve4); 649 } else { 650 blit->fp.code = (uint32_t *)code_nvc0; /* const_cast */ 651 blit->fp.code_size = sizeof(code_nvc0); 652 } 653 blit->fp.max_gpr = 4; 654 655 blit->fp.hdr[0] = 0x00021462; /* fragprog magic */ 656 blit->fp.hdr[5] = 0x80000000; 657 blit->fp.hdr[6] = 0x0000000f; /* 2 linear */ 658 blit->fp.hdr[18] = 0x0000000f; /* 1 colour output */ 659 } 660 661 static void 662 nvc0_blitctx_make_sampler(struct nvc0_blitctx *blit) 663 { 664 /* clamp to edge, min/max lod = 0, nearest filtering */ 665 666 blit->sampler[0].id = -1; 667 668 blit->sampler[0].tsc[0] = NV50_TSC_0_SRGB_CONVERSION_ALLOWED | 669 (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPS__SHIFT) | 670 (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPT__SHIFT) | 671 (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPR__SHIFT); 672 blit->sampler[0].tsc[1] = 673 NV50_TSC_1_MAGF_NEAREST | NV50_TSC_1_MINF_NEAREST | NV50_TSC_1_MIPF_NONE; 674 675 /* clamp to edge, min/max lod = 0, bilinear filtering */ 676 677 blit->sampler[1].id = -1; 678 679 blit->sampler[1].tsc[0] = blit->sampler[0].tsc[0]; 680 blit->sampler[1].tsc[1] = 681 NV50_TSC_1_MAGF_LINEAR | NV50_TSC_1_MINF_LINEAR | NV50_TSC_1_MIPF_NONE; 682 } 683 684 /* Since shaders cannot export stencil, we cannot copy stencil values when 685 * rendering to ZETA, so we attach the ZS surface to a colour render target. 686 */ 687 static INLINE enum pipe_format 688 nvc0_blit_zeta_to_colour_format(enum pipe_format format) 689 { 690 switch (format) { 691 case PIPE_FORMAT_Z16_UNORM: return PIPE_FORMAT_R16_UNORM; 692 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 693 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 694 case PIPE_FORMAT_Z24X8_UNORM: return PIPE_FORMAT_R8G8B8A8_UNORM; 695 case PIPE_FORMAT_Z32_FLOAT: return PIPE_FORMAT_R32_FLOAT; 696 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: return PIPE_FORMAT_R32G32_FLOAT; 697 default: 698 assert(0); 699 return PIPE_FORMAT_NONE; 700 } 701 } 702 703 static void 704 nvc0_blitctx_get_color_mask_and_fp(struct nvc0_blitctx *blit, 705 enum pipe_format format, uint8_t mask) 706 { 707 blit->color_mask = 0; 708 709 switch (format) { 710 case PIPE_FORMAT_Z24X8_UNORM: 711 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 712 blit->fp_offset = 0x180; 713 if (mask & PIPE_MASK_Z) 714 blit->color_mask |= 0x0111; 715 if (mask & PIPE_MASK_S) 716 blit->color_mask |= 0x1000; 717 break; 718 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 719 blit->fp_offset = 0x80; 720 if (mask & PIPE_MASK_Z) 721 blit->color_mask |= 0x1110; 722 if (mask & PIPE_MASK_S) 723 blit->color_mask |= 0x0001; 724 break; 725 default: 726 blit->fp_offset = 0; 727 if (mask & (PIPE_MASK_R | PIPE_MASK_Z)) blit->color_mask |= 0x0001; 728 if (mask & (PIPE_MASK_G | PIPE_MASK_S)) blit->color_mask |= 0x0010; 729 if (mask & PIPE_MASK_B) blit->color_mask |= 0x0100; 730 if (mask & PIPE_MASK_A) blit->color_mask |= 0x1000; 731 break; 732 } 733 } 734 735 static void 736 nvc0_blit_set_dst(struct nvc0_context *nvc0, 737 struct pipe_resource *res, unsigned level, unsigned layer) 738 { 739 struct pipe_context *pipe = &nvc0->base.pipe; 740 struct pipe_surface templ; 741 742 if (util_format_is_depth_or_stencil(res->format)) 743 templ.format = nvc0_blit_zeta_to_colour_format(res->format); 744 else 745 templ.format = res->format; 746 747 templ.usage = PIPE_USAGE_STREAM; 748 templ.u.tex.level = level; 749 templ.u.tex.first_layer = templ.u.tex.last_layer = layer; 750 751 nvc0->framebuffer.cbufs[0] = nvc0_miptree_surface_new(pipe, res, &templ); 752 nvc0->framebuffer.nr_cbufs = 1; 753 nvc0->framebuffer.zsbuf = NULL; 754 nvc0->framebuffer.width = nvc0->framebuffer.cbufs[0]->width; 755 nvc0->framebuffer.height = nvc0->framebuffer.cbufs[0]->height; 756 } 757 758 static INLINE void 759 nvc0_blit_fixup_tic_entry(struct pipe_sampler_view *view, const boolean filter) 760 { 761 struct nv50_tic_entry *ent = nv50_tic_entry(view); 762 763 ent->tic[2] &= ~(1 << 31); /* scaled coordinates, ok with 3d textures ? */ 764 765 /* magic: */ 766 767 if (filter) { 768 /* affects quality of near vertical edges in MS8: */ 769 ent->tic[3] = 0x20000000; 770 } else { 771 ent->tic[3] = 0; 772 ent->tic[6] = 0; 773 } 774 } 775 776 static void 777 nvc0_blit_set_src(struct nvc0_context *nvc0, 778 struct pipe_resource *res, unsigned level, unsigned layer, 779 const boolean filter) 780 { 781 struct pipe_context *pipe = &nvc0->base.pipe; 782 struct pipe_sampler_view templ; 783 int s; 784 785 templ.format = res->format; 786 templ.u.tex.first_layer = templ.u.tex.last_layer = layer; 787 templ.u.tex.first_level = templ.u.tex.last_level = level; 788 templ.swizzle_r = PIPE_SWIZZLE_RED; 789 templ.swizzle_g = PIPE_SWIZZLE_GREEN; 790 templ.swizzle_b = PIPE_SWIZZLE_BLUE; 791 templ.swizzle_a = PIPE_SWIZZLE_ALPHA; 792 793 nvc0->textures[4][0] = nvc0_create_sampler_view(pipe, res, &templ); 794 nvc0->textures[4][1] = NULL; 795 796 nvc0_blit_fixup_tic_entry(nvc0->textures[4][0], filter); 797 798 for (s = 0; s <= 3; ++s) 799 nvc0->num_textures[s] = 0; 800 nvc0->num_textures[4] = 1; 801 802 templ.format = nv50_zs_to_s_format(res->format); 803 if (templ.format != res->format) { 804 nvc0->textures[4][1] = nvc0_create_sampler_view(pipe, res, &templ); 805 nvc0_blit_fixup_tic_entry(nvc0->textures[4][1], filter); 806 nvc0->num_textures[4] = 2; 807 } 808 } 809 810 static void 811 nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit) 812 { 813 struct nouveau_pushbuf *push = blit->screen->base.pushbuf; 814 815 /* TODO: maybe make this a MACRO (if we need more logic) ? */ 816 817 /* blend state */ 818 BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1); 819 PUSH_DATA (push, blit->color_mask); 820 BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1); 821 PUSH_DATA (push, 0); 822 IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0); 823 824 /* rasterizer state */ 825 BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1); 826 PUSH_DATA (push, 0); 827 IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0); 828 BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4); 829 PUSH_DATA (push, 0xffff); 830 PUSH_DATA (push, 0xffff); 831 PUSH_DATA (push, 0xffff); 832 PUSH_DATA (push, 0xffff); 833 BEGIN_NVC0(push, NVC0_3D(MACRO_POLYGON_MODE_FRONT), 1); 834 PUSH_DATA (push, NVC0_3D_MACRO_POLYGON_MODE_FRONT_FILL); 835 BEGIN_NVC0(push, NVC0_3D(MACRO_POLYGON_MODE_BACK), 1); 836 PUSH_DATA (push, NVC0_3D_MACRO_POLYGON_MODE_BACK_FILL); 837 IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0); 838 IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0); 839 IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0); 840 IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0); 841 842 /* zsa state */ 843 IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0); 844 IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0); 845 IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0); 846 847 /* disable transform feedback */ 848 IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0); 849 } 850 851 static void 852 nvc0_blitctx_pre_blit(struct nvc0_blitctx *blit, struct nvc0_context *nvc0) 853 { 854 int s; 855 856 blit->saved.fb.width = nvc0->framebuffer.width; 857 blit->saved.fb.height = nvc0->framebuffer.height; 858 blit->saved.fb.nr_cbufs = nvc0->framebuffer.nr_cbufs; 859 blit->saved.fb.cbufs[0] = nvc0->framebuffer.cbufs[0]; 860 blit->saved.fb.zsbuf = nvc0->framebuffer.zsbuf; 861 862 blit->saved.vp = nvc0->vertprog; 863 blit->saved.tcp = nvc0->tctlprog; 864 blit->saved.tep = nvc0->tevlprog; 865 blit->saved.gp = nvc0->gmtyprog; 866 blit->saved.fp = nvc0->fragprog; 867 868 nvc0->vertprog = &blit->vp; 869 nvc0->fragprog = &blit->fp; 870 nvc0->tctlprog = NULL; 871 nvc0->tevlprog = NULL; 872 nvc0->gmtyprog = NULL; 873 874 for (s = 0; s <= 4; ++s) { 875 blit->saved.num_textures[s] = nvc0->num_textures[s]; 876 blit->saved.num_samplers[s] = nvc0->num_samplers[s]; 877 nvc0->textures_dirty[s] = (1 << nvc0->num_textures[s]) - 1; 878 nvc0->samplers_dirty[s] = (1 << nvc0->num_samplers[s]) - 1; 879 } 880 blit->saved.texture[0] = nvc0->textures[4][0]; 881 blit->saved.texture[1] = nvc0->textures[4][1]; 882 blit->saved.sampler[0] = nvc0->samplers[4][0]; 883 blit->saved.sampler[1] = nvc0->samplers[4][1]; 884 885 nvc0->samplers[4][0] = &blit->sampler[blit->filter]; 886 nvc0->samplers[4][1] = &blit->sampler[blit->filter]; 887 888 for (s = 0; s <= 3; ++s) 889 nvc0->num_samplers[s] = 0; 890 nvc0->num_samplers[4] = 2; 891 892 blit->saved.dirty = nvc0->dirty; 893 894 nvc0->textures_dirty[4] |= 3; 895 nvc0->samplers_dirty[4] |= 3; 896 897 nvc0->dirty = NVC0_NEW_FRAMEBUFFER | 898 NVC0_NEW_VERTPROG | NVC0_NEW_FRAGPROG | 899 NVC0_NEW_TCTLPROG | NVC0_NEW_TEVLPROG | NVC0_NEW_GMTYPROG | 900 NVC0_NEW_TEXTURES | NVC0_NEW_SAMPLERS; 901 } 902 903 static void 904 nvc0_blitctx_post_blit(struct nvc0_context *nvc0, struct nvc0_blitctx *blit) 905 { 906 int s; 907 908 pipe_surface_reference(&nvc0->framebuffer.cbufs[0], NULL); 909 910 nvc0->framebuffer.width = blit->saved.fb.width; 911 nvc0->framebuffer.height = blit->saved.fb.height; 912 nvc0->framebuffer.nr_cbufs = blit->saved.fb.nr_cbufs; 913 nvc0->framebuffer.cbufs[0] = blit->saved.fb.cbufs[0]; 914 nvc0->framebuffer.zsbuf = blit->saved.fb.zsbuf; 915 916 nvc0->vertprog = blit->saved.vp; 917 nvc0->tctlprog = blit->saved.tcp; 918 nvc0->tevlprog = blit->saved.tep; 919 nvc0->gmtyprog = blit->saved.gp; 920 nvc0->fragprog = blit->saved.fp; 921 922 pipe_sampler_view_reference(&nvc0->textures[4][0], NULL); 923 pipe_sampler_view_reference(&nvc0->textures[4][1], NULL); 924 925 for (s = 0; s <= 4; ++s) { 926 nvc0->num_textures[s] = blit->saved.num_textures[s]; 927 nvc0->num_samplers[s] = blit->saved.num_samplers[s]; 928 nvc0->textures_dirty[s] = (1 << nvc0->num_textures[s]) - 1; 929 nvc0->samplers_dirty[s] = (1 << nvc0->num_samplers[s]) - 1; 930 } 931 nvc0->textures[4][0] = blit->saved.texture[0]; 932 nvc0->textures[4][1] = blit->saved.texture[1]; 933 nvc0->samplers[4][0] = blit->saved.sampler[0]; 934 nvc0->samplers[4][1] = blit->saved.sampler[1]; 935 936 nvc0->textures_dirty[4] |= 3; 937 nvc0->samplers_dirty[4] |= 3; 938 939 nvc0->dirty = blit->saved.dirty | 940 (NVC0_NEW_FRAMEBUFFER | NVC0_NEW_SCISSOR | NVC0_NEW_SAMPLE_MASK | 941 NVC0_NEW_RASTERIZER | NVC0_NEW_ZSA | NVC0_NEW_BLEND | 942 NVC0_NEW_TEXTURES | NVC0_NEW_SAMPLERS | 943 NVC0_NEW_VERTPROG | NVC0_NEW_FRAGPROG | 944 NVC0_NEW_TCTLPROG | NVC0_NEW_TEVLPROG | NVC0_NEW_GMTYPROG | 945 NVC0_NEW_TFB_TARGETS); 946 } 947 948 static void 949 nvc0_resource_resolve(struct pipe_context *pipe, 950 const struct pipe_resolve_info *info) 951 { 952 struct nvc0_context *nvc0 = nvc0_context(pipe); 953 struct nvc0_screen *screen = nvc0->screen; 954 struct nvc0_blitctx *blit = screen->blitctx; 955 struct nouveau_pushbuf *push = screen->base.pushbuf; 956 struct pipe_resource *src = info->src.res; 957 struct pipe_resource *dst = info->dst.res; 958 float x0, x1, y0, y1; 959 float x_range, y_range; 960 961 /* Would need more shader variants or, better, just change the TIC target. 962 * But no API creates 3D MS textures ... 963 */ 964 if (src->target == PIPE_TEXTURE_3D) 965 return; 966 967 nvc0_blitctx_get_color_mask_and_fp(blit, dst->format, info->mask); 968 969 blit->filter = util_format_is_depth_or_stencil(dst->format) ? 0 : 1; 970 971 nvc0_blitctx_pre_blit(blit, nvc0); 972 973 nvc0_blit_set_dst(nvc0, dst, info->dst.level, info->dst.layer); 974 nvc0_blit_set_src(nvc0, src, 0, info->src.layer, blit->filter); 975 976 nvc0_blitctx_prepare_state(blit); 977 978 nvc0_state_validate(nvc0, ~0, 36); 979 980 x_range = 981 (float)(info->src.x1 - info->src.x0) / 982 (float)(info->dst.x1 - info->dst.x0); 983 y_range = 984 (float)(info->src.y1 - info->src.y0) / 985 (float)(info->dst.y1 - info->dst.y0); 986 987 x0 = (float)info->src.x0 - x_range * (float)info->dst.x0; 988 y0 = (float)info->src.y0 - y_range * (float)info->dst.y0; 989 990 x1 = x0 + 16384.0f * x_range; 991 y1 = y0 + 16384.0f * y_range; 992 993 x0 *= (float)(1 << nv50_miptree(src)->ms_x); 994 x1 *= (float)(1 << nv50_miptree(src)->ms_x); 995 y0 *= (float)(1 << nv50_miptree(src)->ms_y); 996 y1 *= (float)(1 << nv50_miptree(src)->ms_y); 997 998 BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1); 999 PUSH_DATA (push, 1000 blit->fp.code_base + blit->fp_offset); 1001 1002 IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0); 1003 1004 /* Draw a large triangle in screen coordinates covering the whole 1005 * render target, with scissors defining the destination region. 1006 * The vertex is supplied with non-normalized texture coordinates 1007 * arranged in a way to yield the desired offset and scale. 1008 */ 1009 1010 BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); 1011 PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0); 1012 PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0); 1013 1014 IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1015 NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); 1016 1017 BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); 1018 PUSH_DATA (push, 0x74201); 1019 PUSH_DATAf(push, x0); 1020 PUSH_DATAf(push, y0); 1021 BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); 1022 PUSH_DATA (push, 0x74200); 1023 PUSH_DATAf(push, 0.0f); 1024 PUSH_DATAf(push, 0.0f); 1025 BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); 1026 PUSH_DATA (push, 0x74201); 1027 PUSH_DATAf(push, x1); 1028 PUSH_DATAf(push, y0); 1029 BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); 1030 PUSH_DATA (push, 0x74200); 1031 PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x); 1032 PUSH_DATAf(push, 0.0f); 1033 BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); 1034 PUSH_DATA (push, 0x74201); 1035 PUSH_DATAf(push, x0); 1036 PUSH_DATAf(push, y1); 1037 BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); 1038 PUSH_DATA (push, 0x74200); 1039 PUSH_DATAf(push, 0.0f); 1040 PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y); 1041 1042 IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); 1043 1044 /* re-enable normally constant state */ 1045 1046 IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); 1047 1048 nvc0_blitctx_post_blit(nvc0, blit); 1049 } 1050 1051 boolean 1052 nvc0_blitctx_create(struct nvc0_screen *screen) 1053 { 1054 screen->blitctx = CALLOC_STRUCT(nvc0_blitctx); 1055 if (!screen->blitctx) { 1056 NOUVEAU_ERR("failed to allocate blit context\n"); 1057 return FALSE; 1058 } 1059 1060 screen->blitctx->screen = screen; 1061 1062 nvc0_blitctx_make_vp(screen->blitctx); 1063 nvc0_blitctx_make_fp(screen->blitctx); 1064 1065 nvc0_blitctx_make_sampler(screen->blitctx); 1066 1067 screen->blitctx->color_mask = 0x1111; 1068 1069 return TRUE; 1070 } 1071 1072 1073 void 1074 nvc0_init_surface_functions(struct nvc0_context *nvc0) 1075 { 1076 struct pipe_context *pipe = &nvc0->base.pipe; 1077 1078 pipe->resource_copy_region = nvc0_resource_copy_region; 1079 pipe->resource_resolve = nvc0_resource_resolve; 1080 pipe->clear_render_target = nvc0_clear_render_target; 1081 pipe->clear_depth_stencil = nvc0_clear_depth_stencil; 1082 } 1083 1084