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
nvc0_2d_format_faithful(enum pipe_format format)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
nvc0_2d_format(enum pipe_format format)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
nvc0_2d_texture_set(struct nouveau_pushbuf * push,boolean dst,struct nv50_miptree * mt,unsigned level,unsigned layer)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
nvc0_2d_texture_do_copy(struct nouveau_pushbuf * push,struct nv50_miptree * dst,unsigned dst_level,unsigned dx,unsigned dy,unsigned dz,struct nv50_miptree * src,unsigned src_level,unsigned sx,unsigned sy,unsigned sz,unsigned w,unsigned h)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
nvc0_resource_copy_region(struct pipe_context * pipe,struct pipe_resource * dst,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,struct pipe_resource * src,unsigned src_level,const struct pipe_box * src_box)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
nvc0_clear_render_target(struct pipe_context * pipe,struct pipe_surface * dst,const union pipe_color_union * color,unsigned dstx,unsigned dsty,unsigned width,unsigned height)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
nvc0_clear_depth_stencil(struct pipe_context * pipe,struct pipe_surface * dst,unsigned clear_flags,double depth,unsigned stencil,unsigned dstx,unsigned dsty,unsigned width,unsigned height)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
nvc0_clear(struct pipe_context * pipe,unsigned buffers,const union pipe_color_union * color,double depth,unsigned stencil)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
nvc0_blitctx_make_vp(struct nvc0_blitctx * blit)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
nvc0_blitctx_make_fp(struct nvc0_blitctx * blit)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
nvc0_blitctx_make_sampler(struct nvc0_blitctx * blit)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
nvc0_blit_zeta_to_colour_format(enum pipe_format 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
nvc0_blitctx_get_color_mask_and_fp(struct nvc0_blitctx * blit,enum pipe_format format,uint8_t mask)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
nvc0_blit_set_dst(struct nvc0_context * nvc0,struct pipe_resource * res,unsigned level,unsigned layer)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
nvc0_blit_fixup_tic_entry(struct pipe_sampler_view * view,const boolean filter)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
nvc0_blit_set_src(struct nvc0_context * nvc0,struct pipe_resource * res,unsigned level,unsigned layer,const boolean filter)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
nvc0_blitctx_prepare_state(struct nvc0_blitctx * blit)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
nvc0_blitctx_pre_blit(struct nvc0_blitctx * blit,struct nvc0_context * nvc0)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
nvc0_blitctx_post_blit(struct nvc0_context * nvc0,struct nvc0_blitctx * blit)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
nvc0_resource_resolve(struct pipe_context * pipe,const struct pipe_resolve_info * info)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
nvc0_blitctx_create(struct nvc0_screen * screen)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
nvc0_init_surface_functions(struct nvc0_context * nvc0)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