1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2008 Ben Skeggs 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 12bf215546Sopenharmony_ci * all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include <stdint.h> 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "pipe/p_defines.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "util/u_inlines.h" 28bf215546Sopenharmony_ci#include "util/u_pack_color.h" 29bf215546Sopenharmony_ci#include "util/format/u_format.h" 30bf215546Sopenharmony_ci#include "util/u_surface.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "os/os_thread.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "nvc0/nvc0_context.h" 37bf215546Sopenharmony_ci#include "nvc0/nvc0_resource.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#include "nv50/g80_defs.xml.h" 40bf215546Sopenharmony_ci#include "nv50/g80_texture.xml.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci/* these are used in nv50_blit.h */ 43bf215546Sopenharmony_ci#define NV50_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL 44bf215546Sopenharmony_ci#define NV50_ENG2D_NOCONVERT_FORMATS 0x009cc02000000000ULL 45bf215546Sopenharmony_ci#define NV50_ENG2D_LUMINANCE_FORMATS 0x001cc02000000000ULL 46bf215546Sopenharmony_ci#define NV50_ENG2D_INTENSITY_FORMATS 0x0080000000000000ULL 47bf215546Sopenharmony_ci#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000638000ULL 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci#define NOUVEAU_DRIVER 0xc0 50bf215546Sopenharmony_ci#include "nv50/nv50_blit.h" 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_cistatic inline uint8_t 53bf215546Sopenharmony_cinvc0_2d_format(enum pipe_format format, bool dst, bool dst_src_equal) 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci uint8_t id = nvc0_format_table[format].rt; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci /* A8_UNORM is treated as I8_UNORM as far as the 2D engine is concerned. */ 58bf215546Sopenharmony_ci if (!dst && unlikely(format == PIPE_FORMAT_I8_UNORM) && !dst_src_equal) 59bf215546Sopenharmony_ci return G80_SURFACE_FORMAT_A8_UNORM; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci /* Hardware values for color formats range from 0xc0 to 0xff, 62bf215546Sopenharmony_ci * but the 2D engine doesn't support all of them. 63bf215546Sopenharmony_ci */ 64bf215546Sopenharmony_ci if (nv50_2d_format_supported(format)) 65bf215546Sopenharmony_ci return id; 66bf215546Sopenharmony_ci assert(dst_src_equal); 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci switch (util_format_get_blocksize(format)) { 69bf215546Sopenharmony_ci case 1: 70bf215546Sopenharmony_ci return G80_SURFACE_FORMAT_R8_UNORM; 71bf215546Sopenharmony_ci case 2: 72bf215546Sopenharmony_ci return G80_SURFACE_FORMAT_RG8_UNORM; 73bf215546Sopenharmony_ci case 4: 74bf215546Sopenharmony_ci return G80_SURFACE_FORMAT_BGRA8_UNORM; 75bf215546Sopenharmony_ci case 8: 76bf215546Sopenharmony_ci return G80_SURFACE_FORMAT_RGBA16_UNORM; 77bf215546Sopenharmony_ci case 16: 78bf215546Sopenharmony_ci return G80_SURFACE_FORMAT_RGBA32_FLOAT; 79bf215546Sopenharmony_ci default: 80bf215546Sopenharmony_ci assert(0); 81bf215546Sopenharmony_ci return 0; 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci} 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_cistatic int 86bf215546Sopenharmony_cinvc0_2d_texture_set(struct nouveau_pushbuf *push, bool dst, 87bf215546Sopenharmony_ci struct nv50_miptree *mt, unsigned level, unsigned layer, 88bf215546Sopenharmony_ci enum pipe_format pformat, bool dst_src_pformat_equal) 89bf215546Sopenharmony_ci{ 90bf215546Sopenharmony_ci struct nouveau_bo *bo = mt->base.bo; 91bf215546Sopenharmony_ci uint32_t width, height, depth; 92bf215546Sopenharmony_ci uint32_t format; 93bf215546Sopenharmony_ci uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; 94bf215546Sopenharmony_ci uint32_t offset = mt->level[level].offset; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci format = nvc0_2d_format(pformat, dst, dst_src_pformat_equal); 97bf215546Sopenharmony_ci if (!format) { 98bf215546Sopenharmony_ci NOUVEAU_ERR("invalid/unsupported surface format: %s\n", 99bf215546Sopenharmony_ci util_format_name(pformat)); 100bf215546Sopenharmony_ci return 1; 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci width = u_minify(mt->base.base.width0, level) << mt->ms_x; 104bf215546Sopenharmony_ci height = u_minify(mt->base.base.height0, level) << mt->ms_y; 105bf215546Sopenharmony_ci depth = u_minify(mt->base.base.depth0, level); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci /* layer has to be < depth, and depth > tile depth / 2 */ 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci if (!mt->layout_3d) { 110bf215546Sopenharmony_ci offset += mt->layer_stride * layer; 111bf215546Sopenharmony_ci layer = 0; 112bf215546Sopenharmony_ci depth = 1; 113bf215546Sopenharmony_ci } else 114bf215546Sopenharmony_ci if (!dst) { 115bf215546Sopenharmony_ci offset += nvc0_mt_zslice_offset(mt, level, layer); 116bf215546Sopenharmony_ci layer = 0; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci if (!nouveau_bo_memtype(bo)) { 120bf215546Sopenharmony_ci BEGIN_NVC0(push, SUBC_2D(mthd), 2); 121bf215546Sopenharmony_ci PUSH_DATA (push, format); 122bf215546Sopenharmony_ci PUSH_DATA (push, 1); 123bf215546Sopenharmony_ci BEGIN_NVC0(push, SUBC_2D(mthd + 0x14), 5); 124bf215546Sopenharmony_ci PUSH_DATA (push, mt->level[level].pitch); 125bf215546Sopenharmony_ci PUSH_DATA (push, width); 126bf215546Sopenharmony_ci PUSH_DATA (push, height); 127bf215546Sopenharmony_ci PUSH_DATAh(push, bo->offset + offset); 128bf215546Sopenharmony_ci PUSH_DATA (push, bo->offset + offset); 129bf215546Sopenharmony_ci } else { 130bf215546Sopenharmony_ci BEGIN_NVC0(push, SUBC_2D(mthd), 5); 131bf215546Sopenharmony_ci PUSH_DATA (push, format); 132bf215546Sopenharmony_ci PUSH_DATA (push, 0); 133bf215546Sopenharmony_ci PUSH_DATA (push, mt->level[level].tile_mode); 134bf215546Sopenharmony_ci PUSH_DATA (push, depth); 135bf215546Sopenharmony_ci PUSH_DATA (push, layer); 136bf215546Sopenharmony_ci BEGIN_NVC0(push, SUBC_2D(mthd + 0x18), 4); 137bf215546Sopenharmony_ci PUSH_DATA (push, width); 138bf215546Sopenharmony_ci PUSH_DATA (push, height); 139bf215546Sopenharmony_ci PUSH_DATAh(push, bo->offset + offset); 140bf215546Sopenharmony_ci PUSH_DATA (push, bo->offset + offset); 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci if (dst) { 144bf215546Sopenharmony_ci IMMED_NVC0(push, SUBC_2D(NVC0_2D_SET_DST_COLOR_RENDER_TO_ZETA_SURFACE), 145bf215546Sopenharmony_ci util_format_is_depth_or_stencil(pformat)); 146bf215546Sopenharmony_ci } 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci#if 0 149bf215546Sopenharmony_ci if (dst) { 150bf215546Sopenharmony_ci BEGIN_NVC0(push, SUBC_2D(NVC0_2D_CLIP_X), 4); 151bf215546Sopenharmony_ci PUSH_DATA (push, 0); 152bf215546Sopenharmony_ci PUSH_DATA (push, 0); 153bf215546Sopenharmony_ci PUSH_DATA (push, width); 154bf215546Sopenharmony_ci PUSH_DATA (push, height); 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci#endif 157bf215546Sopenharmony_ci return 0; 158bf215546Sopenharmony_ci} 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_cistatic int 161bf215546Sopenharmony_cinvc0_2d_texture_do_copy(struct nouveau_pushbuf *push, 162bf215546Sopenharmony_ci struct nv50_miptree *dst, unsigned dst_level, 163bf215546Sopenharmony_ci unsigned dx, unsigned dy, unsigned dz, 164bf215546Sopenharmony_ci struct nv50_miptree *src, unsigned src_level, 165bf215546Sopenharmony_ci unsigned sx, unsigned sy, unsigned sz, 166bf215546Sopenharmony_ci unsigned w, unsigned h) 167bf215546Sopenharmony_ci{ 168bf215546Sopenharmony_ci const enum pipe_format dfmt = dst->base.base.format; 169bf215546Sopenharmony_ci const enum pipe_format sfmt = src->base.base.format; 170bf215546Sopenharmony_ci int ret; 171bf215546Sopenharmony_ci bool eqfmt = dfmt == sfmt; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci if (!PUSH_SPACE(push, 2 * 16 + 32)) 174bf215546Sopenharmony_ci return PIPE_ERROR; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci ret = nvc0_2d_texture_set(push, true, dst, dst_level, dz, dfmt, eqfmt); 177bf215546Sopenharmony_ci if (ret) 178bf215546Sopenharmony_ci return ret; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci ret = nvc0_2d_texture_set(push, false, src, src_level, sz, sfmt, eqfmt); 181bf215546Sopenharmony_ci if (ret) 182bf215546Sopenharmony_ci return ret; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(BLIT_CONTROL), 0x00); 185bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4); 186bf215546Sopenharmony_ci PUSH_DATA (push, dx << dst->ms_x); 187bf215546Sopenharmony_ci PUSH_DATA (push, dy << dst->ms_y); 188bf215546Sopenharmony_ci PUSH_DATA (push, w << dst->ms_x); 189bf215546Sopenharmony_ci PUSH_DATA (push, h << dst->ms_y); 190bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4); 191bf215546Sopenharmony_ci PUSH_DATA (push, 0); 192bf215546Sopenharmony_ci PUSH_DATA (push, 1); 193bf215546Sopenharmony_ci PUSH_DATA (push, 0); 194bf215546Sopenharmony_ci PUSH_DATA (push, 1); 195bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4); 196bf215546Sopenharmony_ci PUSH_DATA (push, 0); 197bf215546Sopenharmony_ci PUSH_DATA (push, sx << src->ms_x); 198bf215546Sopenharmony_ci PUSH_DATA (push, 0); 199bf215546Sopenharmony_ci PUSH_DATA (push, sy << src->ms_y); 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci return 0; 202bf215546Sopenharmony_ci} 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_cistatic void 205bf215546Sopenharmony_cinvc0_resource_copy_region(struct pipe_context *pipe, 206bf215546Sopenharmony_ci struct pipe_resource *dst, unsigned dst_level, 207bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 208bf215546Sopenharmony_ci struct pipe_resource *src, unsigned src_level, 209bf215546Sopenharmony_ci const struct pipe_box *src_box) 210bf215546Sopenharmony_ci{ 211bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 212bf215546Sopenharmony_ci int ret; 213bf215546Sopenharmony_ci bool m2mf; 214bf215546Sopenharmony_ci unsigned dst_layer = dstz, src_layer = src_box->z; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 217bf215546Sopenharmony_ci nouveau_copy_buffer(&nvc0->base, 218bf215546Sopenharmony_ci nv04_resource(dst), dstx, 219bf215546Sopenharmony_ci nv04_resource(src), src_box->x, src_box->width); 220bf215546Sopenharmony_ci NOUVEAU_DRV_STAT(&nvc0->screen->base, buf_copy_bytes, src_box->width); 221bf215546Sopenharmony_ci return; 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_copy_count, 1); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci /* 0 and 1 are equal, only supporting 0/1, 2, 4 and 8 */ 226bf215546Sopenharmony_ci assert((src->nr_samples | 1) == (dst->nr_samples | 1)); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci m2mf = (src->format == dst->format) || 229bf215546Sopenharmony_ci (util_format_get_blocksizebits(src->format) == 230bf215546Sopenharmony_ci util_format_get_blocksizebits(dst->format)); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci if (m2mf) { 235bf215546Sopenharmony_ci struct nv50_miptree *src_mt = nv50_miptree(src); 236bf215546Sopenharmony_ci struct nv50_miptree *dst_mt = nv50_miptree(dst); 237bf215546Sopenharmony_ci struct nv50_m2mf_rect drect, srect; 238bf215546Sopenharmony_ci unsigned i; 239bf215546Sopenharmony_ci unsigned nx = util_format_get_nblocksx(src->format, src_box->width) 240bf215546Sopenharmony_ci << src_mt->ms_x; 241bf215546Sopenharmony_ci unsigned ny = util_format_get_nblocksy(src->format, src_box->height) 242bf215546Sopenharmony_ci << src_mt->ms_y; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz); 245bf215546Sopenharmony_ci nv50_m2mf_rect_setup(&srect, src, src_level, 246bf215546Sopenharmony_ci src_box->x, src_box->y, src_box->z); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci for (i = 0; i < src_box->depth; ++i) { 249bf215546Sopenharmony_ci nvc0->m2mf_copy_rect(nvc0, &drect, &srect, nx, ny); 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (dst_mt->layout_3d) 252bf215546Sopenharmony_ci drect.z++; 253bf215546Sopenharmony_ci else 254bf215546Sopenharmony_ci drect.base += dst_mt->layer_stride; 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci if (src_mt->layout_3d) 257bf215546Sopenharmony_ci srect.z++; 258bf215546Sopenharmony_ci else 259bf215546Sopenharmony_ci srect.base += src_mt->layer_stride; 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci return; 262bf215546Sopenharmony_ci } 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci assert(nv50_2d_dst_format_faithful(dst->format)); 265bf215546Sopenharmony_ci assert(nv50_2d_src_format_faithful(src->format)); 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD); 268bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR); 269bf215546Sopenharmony_ci nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx); 270bf215546Sopenharmony_ci nouveau_pushbuf_validate(nvc0->base.pushbuf); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) { 273bf215546Sopenharmony_ci ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf, 274bf215546Sopenharmony_ci nv50_miptree(dst), dst_level, 275bf215546Sopenharmony_ci dstx, dsty, dst_layer, 276bf215546Sopenharmony_ci nv50_miptree(src), src_level, 277bf215546Sopenharmony_ci src_box->x, src_box->y, src_layer, 278bf215546Sopenharmony_ci src_box->width, src_box->height); 279bf215546Sopenharmony_ci if (ret) 280bf215546Sopenharmony_ci break; 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx, 0); 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_cistatic void 286bf215546Sopenharmony_cinvc0_clear_render_target(struct pipe_context *pipe, 287bf215546Sopenharmony_ci struct pipe_surface *dst, 288bf215546Sopenharmony_ci const union pipe_color_union *color, 289bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, 290bf215546Sopenharmony_ci unsigned width, unsigned height, 291bf215546Sopenharmony_ci bool render_condition_enabled) 292bf215546Sopenharmony_ci{ 293bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 294bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 295bf215546Sopenharmony_ci struct nv50_surface *sf = nv50_surface(dst); 296bf215546Sopenharmony_ci struct nv04_resource *res = nv04_resource(sf->base.texture); 297bf215546Sopenharmony_ci unsigned z; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci assert(dst->texture->target != PIPE_BUFFER); 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci if (!PUSH_SPACE(push, 32 + sf->depth)) 302bf215546Sopenharmony_ci return; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci PUSH_REFN (push, res->bo, res->domain | NOUVEAU_BO_WR); 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); 307bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[0]); 308bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[1]); 309bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[2]); 310bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[3]); 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 313bf215546Sopenharmony_ci PUSH_DATA (push, ( width << 16) | dstx); 314bf215546Sopenharmony_ci PUSH_DATA (push, (height << 16) | dsty); 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); 317bf215546Sopenharmony_ci PUSH_DATA (push, 1); 318bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9); 319bf215546Sopenharmony_ci PUSH_DATAh(push, res->address + sf->offset); 320bf215546Sopenharmony_ci PUSH_DATA (push, res->address + sf->offset); 321bf215546Sopenharmony_ci if (likely(nouveau_bo_memtype(res->bo))) { 322bf215546Sopenharmony_ci struct nv50_miptree *mt = nv50_miptree(dst->texture); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci PUSH_DATA(push, sf->width); 325bf215546Sopenharmony_ci PUSH_DATA(push, sf->height); 326bf215546Sopenharmony_ci PUSH_DATA(push, nvc0_format_table[dst->format].rt); 327bf215546Sopenharmony_ci PUSH_DATA(push, (mt->layout_3d << 16) | 328bf215546Sopenharmony_ci mt->level[sf->base.u.tex.level].tile_mode); 329bf215546Sopenharmony_ci PUSH_DATA(push, dst->u.tex.first_layer + sf->depth); 330bf215546Sopenharmony_ci PUSH_DATA(push, mt->layer_stride >> 2); 331bf215546Sopenharmony_ci PUSH_DATA(push, dst->u.tex.first_layer); 332bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode); 333bf215546Sopenharmony_ci } else { 334bf215546Sopenharmony_ci if (res->base.target == PIPE_BUFFER) { 335bf215546Sopenharmony_ci PUSH_DATA(push, 262144); 336bf215546Sopenharmony_ci PUSH_DATA(push, 1); 337bf215546Sopenharmony_ci } else { 338bf215546Sopenharmony_ci PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch); 339bf215546Sopenharmony_ci PUSH_DATA(push, sf->height); 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci PUSH_DATA(push, nvc0_format_table[sf->base.format].rt); 342bf215546Sopenharmony_ci PUSH_DATA(push, 1 << 12); 343bf215546Sopenharmony_ci PUSH_DATA(push, 1); 344bf215546Sopenharmony_ci PUSH_DATA(push, 0); 345bf215546Sopenharmony_ci PUSH_DATA(push, 0); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); 348bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0); 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci /* tiled textures don't have to be fenced, they're not mapped directly */ 351bf215546Sopenharmony_ci nvc0_resource_fence(res, NOUVEAU_BO_WR); 352bf215546Sopenharmony_ci } 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci if (!render_condition_enabled) 355bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS); 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth); 358bf215546Sopenharmony_ci for (z = 0; z < sf->depth; ++z) { 359bf215546Sopenharmony_ci PUSH_DATA (push, 0x3c | 360bf215546Sopenharmony_ci (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 361bf215546Sopenharmony_ci } 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci if (!render_condition_enabled) 364bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode); 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER; 367bf215546Sopenharmony_ci} 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_cistatic void 370bf215546Sopenharmony_cinvc0_clear_buffer_push_nvc0(struct pipe_context *pipe, 371bf215546Sopenharmony_ci struct pipe_resource *res, 372bf215546Sopenharmony_ci unsigned offset, unsigned size, 373bf215546Sopenharmony_ci const void *data, int data_size) 374bf215546Sopenharmony_ci{ 375bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 376bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 377bf215546Sopenharmony_ci struct nv04_resource *buf = nv04_resource(res); 378bf215546Sopenharmony_ci unsigned i; 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci nouveau_bufctx_refn(nvc0->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR); 381bf215546Sopenharmony_ci nouveau_pushbuf_bufctx(push, nvc0->bufctx); 382bf215546Sopenharmony_ci nouveau_pushbuf_validate(push); 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci unsigned count = (size + 3) / 4; 385bf215546Sopenharmony_ci unsigned data_words = data_size / 4; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci while (count) { 388bf215546Sopenharmony_ci unsigned nr_data = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN) / data_words; 389bf215546Sopenharmony_ci unsigned nr = nr_data * data_words; 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci if (!PUSH_SPACE(push, nr + 9)) 392bf215546Sopenharmony_ci break; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); 395bf215546Sopenharmony_ci PUSH_DATAh(push, buf->address + offset); 396bf215546Sopenharmony_ci PUSH_DATA (push, buf->address + offset); 397bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); 398bf215546Sopenharmony_ci PUSH_DATA (push, MIN2(size, nr * 4)); 399bf215546Sopenharmony_ci PUSH_DATA (push, 1); 400bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); 401bf215546Sopenharmony_ci PUSH_DATA (push, 0x100111); 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci /* must not be interrupted (trap on QUERY fence, 0x50 works however) */ 404bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_M2MF(DATA), nr); 405bf215546Sopenharmony_ci for (i = 0; i < nr_data; i++) 406bf215546Sopenharmony_ci PUSH_DATAp(push, data, data_words); 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci count -= nr; 409bf215546Sopenharmony_ci offset += nr * 4; 410bf215546Sopenharmony_ci size -= nr * 4; 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci nvc0_resource_validate(buf, NOUVEAU_BO_WR); 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx, 0); 416bf215546Sopenharmony_ci} 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_cistatic void 419bf215546Sopenharmony_cinvc0_clear_buffer_push_nve4(struct pipe_context *pipe, 420bf215546Sopenharmony_ci struct pipe_resource *res, 421bf215546Sopenharmony_ci unsigned offset, unsigned size, 422bf215546Sopenharmony_ci const void *data, int data_size) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 425bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 426bf215546Sopenharmony_ci struct nv04_resource *buf = nv04_resource(res); 427bf215546Sopenharmony_ci unsigned i; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci nouveau_bufctx_refn(nvc0->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR); 430bf215546Sopenharmony_ci nouveau_pushbuf_bufctx(push, nvc0->bufctx); 431bf215546Sopenharmony_ci nouveau_pushbuf_validate(push); 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci unsigned count = (size + 3) / 4; 434bf215546Sopenharmony_ci unsigned data_words = data_size / 4; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci while (count) { 437bf215546Sopenharmony_ci unsigned nr_data = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN) / data_words; 438bf215546Sopenharmony_ci unsigned nr = nr_data * data_words; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci if (!PUSH_SPACE(push, nr + 10)) 441bf215546Sopenharmony_ci break; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_DST_ADDRESS_HIGH), 2); 444bf215546Sopenharmony_ci PUSH_DATAh(push, buf->address + offset); 445bf215546Sopenharmony_ci PUSH_DATA (push, buf->address + offset); 446bf215546Sopenharmony_ci BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_LINE_LENGTH_IN), 2); 447bf215546Sopenharmony_ci PUSH_DATA (push, MIN2(size, nr * 4)); 448bf215546Sopenharmony_ci PUSH_DATA (push, 1); 449bf215546Sopenharmony_ci /* must not be interrupted (trap on QUERY fence, 0x50 works however) */ 450bf215546Sopenharmony_ci BEGIN_1IC0(push, NVE4_P2MF(UPLOAD_EXEC), nr + 1); 451bf215546Sopenharmony_ci PUSH_DATA (push, 0x1001); 452bf215546Sopenharmony_ci for (i = 0; i < nr_data; i++) 453bf215546Sopenharmony_ci PUSH_DATAp(push, data, data_words); 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci count -= nr; 456bf215546Sopenharmony_ci offset += nr * 4; 457bf215546Sopenharmony_ci size -= nr * 4; 458bf215546Sopenharmony_ci } 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci nvc0_resource_validate(buf, NOUVEAU_BO_WR); 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx, 0); 463bf215546Sopenharmony_ci} 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_cistatic void 466bf215546Sopenharmony_cinvc0_clear_buffer_push(struct pipe_context *pipe, 467bf215546Sopenharmony_ci struct pipe_resource *res, 468bf215546Sopenharmony_ci unsigned offset, unsigned size, 469bf215546Sopenharmony_ci const void *data, int data_size) 470bf215546Sopenharmony_ci{ 471bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 472bf215546Sopenharmony_ci unsigned tmp; 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci if (data_size == 1) { 475bf215546Sopenharmony_ci tmp = *(unsigned char *)data; 476bf215546Sopenharmony_ci tmp = (tmp << 24) | (tmp << 16) | (tmp << 8) | tmp; 477bf215546Sopenharmony_ci data = &tmp; 478bf215546Sopenharmony_ci data_size = 4; 479bf215546Sopenharmony_ci } else if (data_size == 2) { 480bf215546Sopenharmony_ci tmp = *(unsigned short *)data; 481bf215546Sopenharmony_ci tmp = (tmp << 16) | tmp; 482bf215546Sopenharmony_ci data = &tmp; 483bf215546Sopenharmony_ci data_size = 4; 484bf215546Sopenharmony_ci } 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d < NVE4_3D_CLASS) 487bf215546Sopenharmony_ci nvc0_clear_buffer_push_nvc0(pipe, res, offset, size, data, data_size); 488bf215546Sopenharmony_ci else 489bf215546Sopenharmony_ci nvc0_clear_buffer_push_nve4(pipe, res, offset, size, data, data_size); 490bf215546Sopenharmony_ci} 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_cistatic void 493bf215546Sopenharmony_cinvc0_clear_buffer(struct pipe_context *pipe, 494bf215546Sopenharmony_ci struct pipe_resource *res, 495bf215546Sopenharmony_ci unsigned offset, unsigned size, 496bf215546Sopenharmony_ci const void *data, int data_size) 497bf215546Sopenharmony_ci{ 498bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 499bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 500bf215546Sopenharmony_ci struct nv04_resource *buf = nv04_resource(res); 501bf215546Sopenharmony_ci union pipe_color_union color; 502bf215546Sopenharmony_ci enum pipe_format dst_fmt; 503bf215546Sopenharmony_ci unsigned width, height, elements; 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci assert(res->target == PIPE_BUFFER); 506bf215546Sopenharmony_ci assert(nouveau_bo_memtype(buf->bo) == 0); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci switch (data_size) { 509bf215546Sopenharmony_ci case 16: 510bf215546Sopenharmony_ci dst_fmt = PIPE_FORMAT_R32G32B32A32_UINT; 511bf215546Sopenharmony_ci memcpy(&color.ui, data, 16); 512bf215546Sopenharmony_ci break; 513bf215546Sopenharmony_ci case 12: 514bf215546Sopenharmony_ci /* RGB32 is not a valid RT format. This will be handled by the pushbuf 515bf215546Sopenharmony_ci * uploader. 516bf215546Sopenharmony_ci */ 517bf215546Sopenharmony_ci dst_fmt = PIPE_FORMAT_NONE; /* Init dst_fmt to silence gcc warning */ 518bf215546Sopenharmony_ci break; 519bf215546Sopenharmony_ci case 8: 520bf215546Sopenharmony_ci dst_fmt = PIPE_FORMAT_R32G32_UINT; 521bf215546Sopenharmony_ci memcpy(&color.ui, data, 8); 522bf215546Sopenharmony_ci memset(&color.ui[2], 0, 8); 523bf215546Sopenharmony_ci break; 524bf215546Sopenharmony_ci case 4: 525bf215546Sopenharmony_ci dst_fmt = PIPE_FORMAT_R32_UINT; 526bf215546Sopenharmony_ci memcpy(&color.ui, data, 4); 527bf215546Sopenharmony_ci memset(&color.ui[1], 0, 12); 528bf215546Sopenharmony_ci break; 529bf215546Sopenharmony_ci case 2: 530bf215546Sopenharmony_ci dst_fmt = PIPE_FORMAT_R16_UINT; 531bf215546Sopenharmony_ci color.ui[0] = util_cpu_to_le32( 532bf215546Sopenharmony_ci util_le16_to_cpu(*(unsigned short *)data)); 533bf215546Sopenharmony_ci memset(&color.ui[1], 0, 12); 534bf215546Sopenharmony_ci break; 535bf215546Sopenharmony_ci case 1: 536bf215546Sopenharmony_ci dst_fmt = PIPE_FORMAT_R8_UINT; 537bf215546Sopenharmony_ci color.ui[0] = util_cpu_to_le32(*(unsigned char *)data); 538bf215546Sopenharmony_ci memset(&color.ui[1], 0, 12); 539bf215546Sopenharmony_ci break; 540bf215546Sopenharmony_ci default: 541bf215546Sopenharmony_ci assert(!"Unsupported element size"); 542bf215546Sopenharmony_ci return; 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ci util_range_add(&buf->base, &buf->valid_buffer_range, offset, offset + size); 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci assert(size % data_size == 0); 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci if (data_size == 12) { 550bf215546Sopenharmony_ci nvc0_clear_buffer_push(pipe, res, offset, size, data, data_size); 551bf215546Sopenharmony_ci return; 552bf215546Sopenharmony_ci } 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci if (offset & 0xff) { 555bf215546Sopenharmony_ci unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset); 556bf215546Sopenharmony_ci assert(fixup_size % data_size == 0); 557bf215546Sopenharmony_ci nvc0_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size); 558bf215546Sopenharmony_ci offset += fixup_size; 559bf215546Sopenharmony_ci size -= fixup_size; 560bf215546Sopenharmony_ci if (!size) 561bf215546Sopenharmony_ci return; 562bf215546Sopenharmony_ci } 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci elements = size / data_size; 565bf215546Sopenharmony_ci height = (elements + 16383) / 16384; 566bf215546Sopenharmony_ci width = elements / height; 567bf215546Sopenharmony_ci if (height > 1) 568bf215546Sopenharmony_ci width &= ~0xff; 569bf215546Sopenharmony_ci assert(width > 0); 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci if (!PUSH_SPACE(push, 40)) 572bf215546Sopenharmony_ci return; 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR); 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); 577bf215546Sopenharmony_ci PUSH_DATA (push, color.ui[0]); 578bf215546Sopenharmony_ci PUSH_DATA (push, color.ui[1]); 579bf215546Sopenharmony_ci PUSH_DATA (push, color.ui[2]); 580bf215546Sopenharmony_ci PUSH_DATA (push, color.ui[3]); 581bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 582bf215546Sopenharmony_ci PUSH_DATA (push, width << 16); 583bf215546Sopenharmony_ci PUSH_DATA (push, height << 16); 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(RT_CONTROL), 1); 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9); 588bf215546Sopenharmony_ci PUSH_DATAh(push, buf->address + offset); 589bf215546Sopenharmony_ci PUSH_DATA (push, buf->address + offset); 590bf215546Sopenharmony_ci PUSH_DATA (push, align(width * data_size, 0x100)); 591bf215546Sopenharmony_ci PUSH_DATA (push, height); 592bf215546Sopenharmony_ci PUSH_DATA (push, nvc0_format_table[dst_fmt].rt); 593bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_RT_TILE_MODE_LINEAR); 594bf215546Sopenharmony_ci PUSH_DATA (push, 1); 595bf215546Sopenharmony_ci PUSH_DATA (push, 0); 596bf215546Sopenharmony_ci PUSH_DATA (push, 0); 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); 599bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0); 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c); 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode); 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci nvc0_resource_validate(buf, NOUVEAU_BO_WR); 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci if (width * height != elements) { 610bf215546Sopenharmony_ci offset += width * height * data_size; 611bf215546Sopenharmony_ci width = elements - width * height; 612bf215546Sopenharmony_ci nvc0_clear_buffer_push(pipe, res, offset, width * data_size, 613bf215546Sopenharmony_ci data, data_size); 614bf215546Sopenharmony_ci } 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER; 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_cistatic void 620bf215546Sopenharmony_cinvc0_clear_depth_stencil(struct pipe_context *pipe, 621bf215546Sopenharmony_ci struct pipe_surface *dst, 622bf215546Sopenharmony_ci unsigned clear_flags, 623bf215546Sopenharmony_ci double depth, 624bf215546Sopenharmony_ci unsigned stencil, 625bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, 626bf215546Sopenharmony_ci unsigned width, unsigned height, 627bf215546Sopenharmony_ci bool render_condition_enabled) 628bf215546Sopenharmony_ci{ 629bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 630bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 631bf215546Sopenharmony_ci struct nv50_miptree *mt = nv50_miptree(dst->texture); 632bf215546Sopenharmony_ci struct nv50_surface *sf = nv50_surface(dst); 633bf215546Sopenharmony_ci uint32_t mode = 0; 634bf215546Sopenharmony_ci int unk = mt->base.base.target == PIPE_TEXTURE_2D; 635bf215546Sopenharmony_ci unsigned z; 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci assert(dst->texture->target != PIPE_BUFFER); 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_ci if (!PUSH_SPACE(push, 32 + sf->depth)) 640bf215546Sopenharmony_ci return; 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_ci PUSH_REFN (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR); 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci if (clear_flags & PIPE_CLEAR_DEPTH) { 645bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1); 646bf215546Sopenharmony_ci PUSH_DATAf(push, depth); 647bf215546Sopenharmony_ci mode |= NVC0_3D_CLEAR_BUFFERS_Z; 648bf215546Sopenharmony_ci } 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci if (clear_flags & PIPE_CLEAR_STENCIL) { 651bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1); 652bf215546Sopenharmony_ci PUSH_DATA (push, stencil & 0xff); 653bf215546Sopenharmony_ci mode |= NVC0_3D_CLEAR_BUFFERS_S; 654bf215546Sopenharmony_ci } 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 657bf215546Sopenharmony_ci PUSH_DATA (push, ( width << 16) | dstx); 658bf215546Sopenharmony_ci PUSH_DATA (push, (height << 16) | dsty); 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5); 661bf215546Sopenharmony_ci PUSH_DATAh(push, mt->base.address + sf->offset); 662bf215546Sopenharmony_ci PUSH_DATA (push, mt->base.address + sf->offset); 663bf215546Sopenharmony_ci PUSH_DATA (push, nvc0_format_table[dst->format].rt); 664bf215546Sopenharmony_ci PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); 665bf215546Sopenharmony_ci PUSH_DATA (push, mt->layer_stride >> 2); 666bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); 667bf215546Sopenharmony_ci PUSH_DATA (push, 1); 668bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3); 669bf215546Sopenharmony_ci PUSH_DATA (push, sf->width); 670bf215546Sopenharmony_ci PUSH_DATA (push, sf->height); 671bf215546Sopenharmony_ci PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth)); 672bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1); 673bf215546Sopenharmony_ci PUSH_DATA (push, dst->u.tex.first_layer); 674bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode); 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci if (!render_condition_enabled) 677bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS); 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth); 680bf215546Sopenharmony_ci for (z = 0; z < sf->depth; ++z) { 681bf215546Sopenharmony_ci PUSH_DATA (push, mode | 682bf215546Sopenharmony_ci (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 683bf215546Sopenharmony_ci } 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci if (!render_condition_enabled) 686bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode); 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER; 689bf215546Sopenharmony_ci} 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_civoid 692bf215546Sopenharmony_cinvc0_clear(struct pipe_context *pipe, unsigned buffers, 693bf215546Sopenharmony_ci const struct pipe_scissor_state *scissor_state, 694bf215546Sopenharmony_ci const union pipe_color_union *color, 695bf215546Sopenharmony_ci double depth, unsigned stencil) 696bf215546Sopenharmony_ci{ 697bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 698bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 699bf215546Sopenharmony_ci struct pipe_framebuffer_state *fb = &nvc0->framebuffer; 700bf215546Sopenharmony_ci unsigned i, j, k; 701bf215546Sopenharmony_ci uint32_t mode = 0; 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ci /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */ 704bf215546Sopenharmony_ci if (!nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER)) 705bf215546Sopenharmony_ci return; 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci if (scissor_state) { 708bf215546Sopenharmony_ci uint32_t minx = scissor_state->minx; 709bf215546Sopenharmony_ci uint32_t maxx = MIN2(fb->width, scissor_state->maxx); 710bf215546Sopenharmony_ci uint32_t miny = scissor_state->miny; 711bf215546Sopenharmony_ci uint32_t maxy = MIN2(fb->height, scissor_state->maxy); 712bf215546Sopenharmony_ci if (maxx <= minx || maxy <= miny) 713bf215546Sopenharmony_ci return; 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 716bf215546Sopenharmony_ci PUSH_DATA (push, minx | (maxx - minx) << 16); 717bf215546Sopenharmony_ci PUSH_DATA (push, miny | (maxy - miny) << 16); 718bf215546Sopenharmony_ci } 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { 721bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); 722bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[0]); 723bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[1]); 724bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[2]); 725bf215546Sopenharmony_ci PUSH_DATAf(push, color->f[3]); 726bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_COLOR0) 727bf215546Sopenharmony_ci mode = 728bf215546Sopenharmony_ci NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G | 729bf215546Sopenharmony_ci NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A; 730bf215546Sopenharmony_ci } 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_DEPTH) { 733bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1); 734bf215546Sopenharmony_ci PUSH_DATA (push, fui(depth)); 735bf215546Sopenharmony_ci mode |= NVC0_3D_CLEAR_BUFFERS_Z; 736bf215546Sopenharmony_ci } 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_STENCIL) { 739bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1); 740bf215546Sopenharmony_ci PUSH_DATA (push, stencil & 0xff); 741bf215546Sopenharmony_ci mode |= NVC0_3D_CLEAR_BUFFERS_S; 742bf215546Sopenharmony_ci } 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_ci if (mode) { 745bf215546Sopenharmony_ci int zs_layers = 0, color0_layers = 0; 746bf215546Sopenharmony_ci if (fb->cbufs[0] && (mode & 0x3c)) 747bf215546Sopenharmony_ci color0_layers = fb->cbufs[0]->u.tex.last_layer - 748bf215546Sopenharmony_ci fb->cbufs[0]->u.tex.first_layer + 1; 749bf215546Sopenharmony_ci if (fb->zsbuf && (mode & ~0x3c)) 750bf215546Sopenharmony_ci zs_layers = fb->zsbuf->u.tex.last_layer - 751bf215546Sopenharmony_ci fb->zsbuf->u.tex.first_layer + 1; 752bf215546Sopenharmony_ci 753bf215546Sopenharmony_ci for (j = 0; j < MIN2(zs_layers, color0_layers); j++) { 754bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 755bf215546Sopenharmony_ci PUSH_DATA(push, mode | (j << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 756bf215546Sopenharmony_ci } 757bf215546Sopenharmony_ci for (k = j; k < zs_layers; k++) { 758bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 759bf215546Sopenharmony_ci PUSH_DATA(push, (mode & ~0x3c) | (k << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 760bf215546Sopenharmony_ci } 761bf215546Sopenharmony_ci for (k = j; k < color0_layers; k++) { 762bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 763bf215546Sopenharmony_ci PUSH_DATA(push, (mode & 0x3c) | (k << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 764bf215546Sopenharmony_ci } 765bf215546Sopenharmony_ci } 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ci for (i = 1; i < fb->nr_cbufs; i++) { 768bf215546Sopenharmony_ci struct pipe_surface *sf = fb->cbufs[i]; 769bf215546Sopenharmony_ci if (!sf || !(buffers & (PIPE_CLEAR_COLOR0 << i))) 770bf215546Sopenharmony_ci continue; 771bf215546Sopenharmony_ci for (j = 0; j <= sf->u.tex.last_layer - sf->u.tex.first_layer; j++) { 772bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); 773bf215546Sopenharmony_ci PUSH_DATA (push, (i << 6) | 0x3c | 774bf215546Sopenharmony_ci (j << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); 775bf215546Sopenharmony_ci } 776bf215546Sopenharmony_ci } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci /* restore screen scissor */ 779bf215546Sopenharmony_ci if (scissor_state) { 780bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); 781bf215546Sopenharmony_ci PUSH_DATA (push, fb->width << 16); 782bf215546Sopenharmony_ci PUSH_DATA (push, fb->height << 16); 783bf215546Sopenharmony_ci } 784bf215546Sopenharmony_ci} 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_cistatic void 787bf215546Sopenharmony_cigm200_evaluate_depth_buffer(struct pipe_context *pipe) 788bf215546Sopenharmony_ci{ 789bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 790bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER); 793bf215546Sopenharmony_ci IMMED_NVC0(push, SUBC_3D(0x11fc), 1); 794bf215546Sopenharmony_ci} 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci/* =============================== BLIT CODE =================================== 798bf215546Sopenharmony_ci */ 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_cistruct nvc0_blitter 801bf215546Sopenharmony_ci{ 802bf215546Sopenharmony_ci struct nvc0_program *fp[NV50_BLIT_MAX_TEXTURE_TYPES][NV50_BLIT_MODES]; 803bf215546Sopenharmony_ci struct nvc0_program *vp; 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */ 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci mtx_t mutex; 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci struct nvc0_screen *screen; 810bf215546Sopenharmony_ci}; 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_cistruct nvc0_blitctx 813bf215546Sopenharmony_ci{ 814bf215546Sopenharmony_ci struct nvc0_context *nvc0; 815bf215546Sopenharmony_ci struct nvc0_program *fp; 816bf215546Sopenharmony_ci struct nvc0_program *vp; 817bf215546Sopenharmony_ci uint8_t mode; 818bf215546Sopenharmony_ci uint16_t color_mask; 819bf215546Sopenharmony_ci uint8_t filter; 820bf215546Sopenharmony_ci uint8_t render_condition_enable; 821bf215546Sopenharmony_ci enum pipe_texture_target target; 822bf215546Sopenharmony_ci struct { 823bf215546Sopenharmony_ci struct pipe_framebuffer_state fb; 824bf215546Sopenharmony_ci struct nvc0_window_rect_stateobj window_rect; 825bf215546Sopenharmony_ci struct nvc0_rasterizer_stateobj *rast; 826bf215546Sopenharmony_ci struct nvc0_program *vp; 827bf215546Sopenharmony_ci struct nvc0_program *tcp; 828bf215546Sopenharmony_ci struct nvc0_program *tep; 829bf215546Sopenharmony_ci struct nvc0_program *gp; 830bf215546Sopenharmony_ci struct nvc0_program *fp; 831bf215546Sopenharmony_ci unsigned num_textures[5]; 832bf215546Sopenharmony_ci unsigned num_samplers[5]; 833bf215546Sopenharmony_ci struct pipe_sampler_view *texture[2]; 834bf215546Sopenharmony_ci struct nv50_tsc_entry *sampler[2]; 835bf215546Sopenharmony_ci unsigned min_samples; 836bf215546Sopenharmony_ci uint32_t dirty_3d; 837bf215546Sopenharmony_ci } saved; 838bf215546Sopenharmony_ci struct nvc0_rasterizer_stateobj rast; 839bf215546Sopenharmony_ci}; 840bf215546Sopenharmony_ci 841bf215546Sopenharmony_cistatic void * 842bf215546Sopenharmony_cinvc0_blitter_make_vp(struct pipe_context *pipe) 843bf215546Sopenharmony_ci{ 844bf215546Sopenharmony_ci struct ureg_program *ureg; 845bf215546Sopenharmony_ci struct ureg_src ipos, itex; 846bf215546Sopenharmony_ci struct ureg_dst opos, otex; 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_VERTEX); 849bf215546Sopenharmony_ci if (!ureg) 850bf215546Sopenharmony_ci return NULL; 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci opos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 853bf215546Sopenharmony_ci ipos = ureg_DECL_vs_input(ureg, 0); 854bf215546Sopenharmony_ci otex = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 855bf215546Sopenharmony_ci itex = ureg_DECL_vs_input(ureg, 1); 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(opos, TGSI_WRITEMASK_XY ), ipos); 858bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(otex, TGSI_WRITEMASK_XYZ), itex); 859bf215546Sopenharmony_ci ureg_END(ureg); 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 862bf215546Sopenharmony_ci} 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_cistatic void 865bf215546Sopenharmony_cinvc0_blitter_make_sampler(struct nvc0_blitter *blit) 866bf215546Sopenharmony_ci{ 867bf215546Sopenharmony_ci /* clamp to edge, min/max lod = 0, nearest filtering */ 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci blit->sampler[0].id = -1; 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci blit->sampler[0].tsc[0] = G80_TSC_0_SRGB_CONVERSION | 872bf215546Sopenharmony_ci (G80_TSC_WRAP_CLAMP_TO_EDGE << G80_TSC_0_ADDRESS_U__SHIFT) | 873bf215546Sopenharmony_ci (G80_TSC_WRAP_CLAMP_TO_EDGE << G80_TSC_0_ADDRESS_V__SHIFT) | 874bf215546Sopenharmony_ci (G80_TSC_WRAP_CLAMP_TO_EDGE << G80_TSC_0_ADDRESS_P__SHIFT); 875bf215546Sopenharmony_ci blit->sampler[0].tsc[1] = 876bf215546Sopenharmony_ci G80_TSC_1_MAG_FILTER_NEAREST | 877bf215546Sopenharmony_ci G80_TSC_1_MIN_FILTER_NEAREST | 878bf215546Sopenharmony_ci G80_TSC_1_MIP_FILTER_NONE; 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci /* clamp to edge, min/max lod = 0, bilinear filtering */ 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci blit->sampler[1].id = -1; 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci blit->sampler[1].tsc[0] = blit->sampler[0].tsc[0]; 885bf215546Sopenharmony_ci blit->sampler[1].tsc[1] = 886bf215546Sopenharmony_ci G80_TSC_1_MAG_FILTER_LINEAR | 887bf215546Sopenharmony_ci G80_TSC_1_MIN_FILTER_LINEAR | 888bf215546Sopenharmony_ci G80_TSC_1_MIP_FILTER_NONE; 889bf215546Sopenharmony_ci} 890bf215546Sopenharmony_ci 891bf215546Sopenharmony_cistatic void 892bf215546Sopenharmony_cinvc0_blit_select_vp(struct nvc0_blitctx *ctx) 893bf215546Sopenharmony_ci{ 894bf215546Sopenharmony_ci struct nvc0_blitter *blitter = ctx->nvc0->screen->blitter; 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci if (!blitter->vp) { 897bf215546Sopenharmony_ci mtx_lock(&blitter->mutex); 898bf215546Sopenharmony_ci if (!blitter->vp) 899bf215546Sopenharmony_ci blitter->vp = nvc0_blitter_make_vp(&ctx->nvc0->base.pipe); 900bf215546Sopenharmony_ci mtx_unlock(&blitter->mutex); 901bf215546Sopenharmony_ci } 902bf215546Sopenharmony_ci ctx->vp = blitter->vp; 903bf215546Sopenharmony_ci} 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_cistatic void 906bf215546Sopenharmony_cinvc0_blit_select_fp(struct nvc0_blitctx *ctx, const struct pipe_blit_info *info) 907bf215546Sopenharmony_ci{ 908bf215546Sopenharmony_ci struct nvc0_blitter *blitter = ctx->nvc0->screen->blitter; 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci const enum pipe_texture_target ptarg = 911bf215546Sopenharmony_ci nv50_blit_reinterpret_pipe_texture_target(info->src.resource->target); 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci const unsigned targ = nv50_blit_texture_type(ptarg); 914bf215546Sopenharmony_ci const unsigned mode = ctx->mode; 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_ci if (!blitter->fp[targ][mode]) { 917bf215546Sopenharmony_ci mtx_lock(&blitter->mutex); 918bf215546Sopenharmony_ci if (!blitter->fp[targ][mode]) 919bf215546Sopenharmony_ci blitter->fp[targ][mode] = 920bf215546Sopenharmony_ci nv50_blitter_make_fp(&ctx->nvc0->base.pipe, mode, ptarg); 921bf215546Sopenharmony_ci mtx_unlock(&blitter->mutex); 922bf215546Sopenharmony_ci } 923bf215546Sopenharmony_ci ctx->fp = blitter->fp[targ][mode]; 924bf215546Sopenharmony_ci} 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_cistatic void 927bf215546Sopenharmony_cinvc0_blit_set_dst(struct nvc0_blitctx *ctx, 928bf215546Sopenharmony_ci struct pipe_resource *res, unsigned level, unsigned layer, 929bf215546Sopenharmony_ci enum pipe_format format) 930bf215546Sopenharmony_ci{ 931bf215546Sopenharmony_ci struct nvc0_context *nvc0 = ctx->nvc0; 932bf215546Sopenharmony_ci struct pipe_context *pipe = &nvc0->base.pipe; 933bf215546Sopenharmony_ci struct pipe_surface templ; 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(format)) 936bf215546Sopenharmony_ci templ.format = nv50_blit_zeta_to_colour_format(format); 937bf215546Sopenharmony_ci else 938bf215546Sopenharmony_ci templ.format = format; 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci templ.u.tex.level = level; 941bf215546Sopenharmony_ci templ.u.tex.first_layer = templ.u.tex.last_layer = layer; 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci if (layer == -1) { 944bf215546Sopenharmony_ci templ.u.tex.first_layer = 0; 945bf215546Sopenharmony_ci templ.u.tex.last_layer = 946bf215546Sopenharmony_ci (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1; 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci nvc0->framebuffer.cbufs[0] = nvc0_miptree_surface_new(pipe, res, &templ); 950bf215546Sopenharmony_ci nvc0->framebuffer.nr_cbufs = 1; 951bf215546Sopenharmony_ci nvc0->framebuffer.zsbuf = NULL; 952bf215546Sopenharmony_ci nvc0->framebuffer.width = nvc0->framebuffer.cbufs[0]->width; 953bf215546Sopenharmony_ci nvc0->framebuffer.height = nvc0->framebuffer.cbufs[0]->height; 954bf215546Sopenharmony_ci} 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_cistatic void 957bf215546Sopenharmony_cinvc0_blit_set_src(struct nvc0_blitctx *ctx, 958bf215546Sopenharmony_ci struct pipe_resource *res, unsigned level, unsigned layer, 959bf215546Sopenharmony_ci enum pipe_format format, const uint8_t filter) 960bf215546Sopenharmony_ci{ 961bf215546Sopenharmony_ci struct nvc0_context *nvc0 = ctx->nvc0; 962bf215546Sopenharmony_ci struct pipe_context *pipe = &nvc0->base.pipe; 963bf215546Sopenharmony_ci struct pipe_sampler_view templ; 964bf215546Sopenharmony_ci uint32_t flags; 965bf215546Sopenharmony_ci unsigned s; 966bf215546Sopenharmony_ci enum pipe_texture_target target; 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci target = nv50_blit_reinterpret_pipe_texture_target(res->target); 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci templ.target = target; 971bf215546Sopenharmony_ci templ.format = format; 972bf215546Sopenharmony_ci templ.u.tex.first_layer = templ.u.tex.last_layer = layer; 973bf215546Sopenharmony_ci templ.u.tex.first_level = templ.u.tex.last_level = level; 974bf215546Sopenharmony_ci templ.swizzle_r = PIPE_SWIZZLE_X; 975bf215546Sopenharmony_ci templ.swizzle_g = PIPE_SWIZZLE_Y; 976bf215546Sopenharmony_ci templ.swizzle_b = PIPE_SWIZZLE_Z; 977bf215546Sopenharmony_ci templ.swizzle_a = PIPE_SWIZZLE_W; 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci if (layer == -1) { 980bf215546Sopenharmony_ci templ.u.tex.first_layer = 0; 981bf215546Sopenharmony_ci templ.u.tex.last_layer = 982bf215546Sopenharmony_ci (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1; 983bf215546Sopenharmony_ci } 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci flags = res->last_level ? 0 : NV50_TEXVIEW_SCALED_COORDS; 986bf215546Sopenharmony_ci flags |= NV50_TEXVIEW_ACCESS_RESOLVE; 987bf215546Sopenharmony_ci if (filter && res->nr_samples == 8) 988bf215546Sopenharmony_ci flags |= NV50_TEXVIEW_FILTER_MSAA8; 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_ci nvc0->textures[4][0] = nvc0_create_texture_view( 991bf215546Sopenharmony_ci pipe, res, &templ, flags); 992bf215546Sopenharmony_ci nvc0->textures[4][1] = NULL; 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_ci for (s = 0; s <= 3; ++s) 995bf215546Sopenharmony_ci nvc0->num_textures[s] = 0; 996bf215546Sopenharmony_ci nvc0->num_textures[4] = 1; 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci templ.format = nv50_zs_to_s_format(format); 999bf215546Sopenharmony_ci if (templ.format != format) { 1000bf215546Sopenharmony_ci nvc0->textures[4][1] = nvc0_create_texture_view( 1001bf215546Sopenharmony_ci pipe, res, &templ, flags); 1002bf215546Sopenharmony_ci nvc0->num_textures[4] = 2; 1003bf215546Sopenharmony_ci } 1004bf215546Sopenharmony_ci} 1005bf215546Sopenharmony_ci 1006bf215546Sopenharmony_cistatic void 1007bf215546Sopenharmony_cinvc0_blitctx_prepare_state(struct nvc0_blitctx *blit) 1008bf215546Sopenharmony_ci{ 1009bf215546Sopenharmony_ci struct nouveau_pushbuf *push = blit->nvc0->base.pushbuf; 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci /* TODO: maybe make this a MACRO (if we need more logic) ? */ 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci if (blit->nvc0->cond_query && !blit->render_condition_enable) 1014bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS); 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci /* blend state */ 1017bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1); 1018bf215546Sopenharmony_ci PUSH_DATA (push, blit->color_mask); 1019bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 0); 1020bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0); 1021bf215546Sopenharmony_ci 1022bf215546Sopenharmony_ci /* rasterizer state */ 1023bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 0); 1024bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0); 1025bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4); 1026bf215546Sopenharmony_ci PUSH_DATA (push, 0xffff); 1027bf215546Sopenharmony_ci PUSH_DATA (push, 0xffff); 1028bf215546Sopenharmony_ci PUSH_DATA (push, 0xffff); 1029bf215546Sopenharmony_ci PUSH_DATA (push, 0xffff); 1030bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(MACRO_POLYGON_MODE_FRONT), 1); 1031bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_MACRO_POLYGON_MODE_FRONT_FILL); 1032bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(MACRO_POLYGON_MODE_BACK), 1); 1033bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_MACRO_POLYGON_MODE_BACK_FILL); 1034bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0); 1035bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0); 1036bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0); 1037bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0); 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci /* zsa state */ 1040bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0); 1041bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(DEPTH_BOUNDS_EN), 0); 1042bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0); 1043bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0); 1044bf215546Sopenharmony_ci 1045bf215546Sopenharmony_ci /* disable transform feedback */ 1046bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0); 1047bf215546Sopenharmony_ci} 1048bf215546Sopenharmony_ci 1049bf215546Sopenharmony_cistatic void 1050bf215546Sopenharmony_cinvc0_blitctx_pre_blit(struct nvc0_blitctx *ctx, 1051bf215546Sopenharmony_ci const struct pipe_blit_info *info) 1052bf215546Sopenharmony_ci{ 1053bf215546Sopenharmony_ci struct nvc0_context *nvc0 = ctx->nvc0; 1054bf215546Sopenharmony_ci struct nvc0_blitter *blitter = nvc0->screen->blitter; 1055bf215546Sopenharmony_ci int s; 1056bf215546Sopenharmony_ci 1057bf215546Sopenharmony_ci ctx->saved.fb.width = nvc0->framebuffer.width; 1058bf215546Sopenharmony_ci ctx->saved.fb.height = nvc0->framebuffer.height; 1059bf215546Sopenharmony_ci ctx->saved.fb.samples = nvc0->framebuffer.samples; 1060bf215546Sopenharmony_ci ctx->saved.fb.layers = nvc0->framebuffer.layers; 1061bf215546Sopenharmony_ci ctx->saved.fb.nr_cbufs = nvc0->framebuffer.nr_cbufs; 1062bf215546Sopenharmony_ci ctx->saved.fb.cbufs[0] = nvc0->framebuffer.cbufs[0]; 1063bf215546Sopenharmony_ci ctx->saved.fb.zsbuf = nvc0->framebuffer.zsbuf; 1064bf215546Sopenharmony_ci 1065bf215546Sopenharmony_ci ctx->saved.rast = nvc0->rast; 1066bf215546Sopenharmony_ci 1067bf215546Sopenharmony_ci ctx->saved.vp = nvc0->vertprog; 1068bf215546Sopenharmony_ci ctx->saved.tcp = nvc0->tctlprog; 1069bf215546Sopenharmony_ci ctx->saved.tep = nvc0->tevlprog; 1070bf215546Sopenharmony_ci ctx->saved.gp = nvc0->gmtyprog; 1071bf215546Sopenharmony_ci ctx->saved.fp = nvc0->fragprog; 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci ctx->saved.min_samples = nvc0->min_samples; 1074bf215546Sopenharmony_ci ctx->saved.window_rect = nvc0->window_rect; 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci nvc0->rast = &ctx->rast; 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_ci nvc0->vertprog = ctx->vp; 1079bf215546Sopenharmony_ci nvc0->tctlprog = NULL; 1080bf215546Sopenharmony_ci nvc0->tevlprog = NULL; 1081bf215546Sopenharmony_ci nvc0->gmtyprog = NULL; 1082bf215546Sopenharmony_ci nvc0->fragprog = ctx->fp; 1083bf215546Sopenharmony_ci 1084bf215546Sopenharmony_ci nvc0->window_rect.rects = 1085bf215546Sopenharmony_ci MIN2(info->num_window_rectangles, NVC0_MAX_WINDOW_RECTANGLES); 1086bf215546Sopenharmony_ci nvc0->window_rect.inclusive = info->window_rectangle_include; 1087bf215546Sopenharmony_ci if (nvc0->window_rect.rects) 1088bf215546Sopenharmony_ci memcpy(nvc0->window_rect.rect, info->window_rectangles, 1089bf215546Sopenharmony_ci sizeof(struct pipe_scissor_state) * nvc0->window_rect.rects); 1090bf215546Sopenharmony_ci 1091bf215546Sopenharmony_ci for (s = 0; s <= 4; ++s) { 1092bf215546Sopenharmony_ci ctx->saved.num_textures[s] = nvc0->num_textures[s]; 1093bf215546Sopenharmony_ci ctx->saved.num_samplers[s] = nvc0->num_samplers[s]; 1094bf215546Sopenharmony_ci nvc0->textures_dirty[s] = (1 << nvc0->num_textures[s]) - 1; 1095bf215546Sopenharmony_ci nvc0->samplers_dirty[s] = (1 << nvc0->num_samplers[s]) - 1; 1096bf215546Sopenharmony_ci } 1097bf215546Sopenharmony_ci ctx->saved.texture[0] = nvc0->textures[4][0]; 1098bf215546Sopenharmony_ci ctx->saved.texture[1] = nvc0->textures[4][1]; 1099bf215546Sopenharmony_ci ctx->saved.sampler[0] = nvc0->samplers[4][0]; 1100bf215546Sopenharmony_ci ctx->saved.sampler[1] = nvc0->samplers[4][1]; 1101bf215546Sopenharmony_ci 1102bf215546Sopenharmony_ci nvc0->samplers[4][0] = &blitter->sampler[ctx->filter]; 1103bf215546Sopenharmony_ci nvc0->samplers[4][1] = &blitter->sampler[ctx->filter]; 1104bf215546Sopenharmony_ci 1105bf215546Sopenharmony_ci for (s = 0; s <= 3; ++s) 1106bf215546Sopenharmony_ci nvc0->num_samplers[s] = 0; 1107bf215546Sopenharmony_ci nvc0->num_samplers[4] = 2; 1108bf215546Sopenharmony_ci 1109bf215546Sopenharmony_ci nvc0->min_samples = 1; 1110bf215546Sopenharmony_ci 1111bf215546Sopenharmony_ci ctx->saved.dirty_3d = nvc0->dirty_3d; 1112bf215546Sopenharmony_ci 1113bf215546Sopenharmony_ci nvc0->textures_dirty[4] |= 3; 1114bf215546Sopenharmony_ci nvc0->samplers_dirty[4] |= 3; 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB); 1117bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(4, 0)); 1118bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(4, 1)); 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci nvc0->dirty_3d = NVC0_NEW_3D_FRAMEBUFFER | NVC0_NEW_3D_MIN_SAMPLES | 1121bf215546Sopenharmony_ci NVC0_NEW_3D_VERTPROG | NVC0_NEW_3D_FRAGPROG | 1122bf215546Sopenharmony_ci NVC0_NEW_3D_TCTLPROG | NVC0_NEW_3D_TEVLPROG | NVC0_NEW_3D_GMTYPROG | 1123bf215546Sopenharmony_ci NVC0_NEW_3D_TEXTURES | NVC0_NEW_3D_SAMPLERS | NVC0_NEW_3D_WINDOW_RECTS; 1124bf215546Sopenharmony_ci} 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_cistatic void 1127bf215546Sopenharmony_cinvc0_blitctx_post_blit(struct nvc0_blitctx *blit) 1128bf215546Sopenharmony_ci{ 1129bf215546Sopenharmony_ci struct nvc0_context *nvc0 = blit->nvc0; 1130bf215546Sopenharmony_ci int s; 1131bf215546Sopenharmony_ci 1132bf215546Sopenharmony_ci pipe_surface_reference(&nvc0->framebuffer.cbufs[0], NULL); 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci nvc0->framebuffer.width = blit->saved.fb.width; 1135bf215546Sopenharmony_ci nvc0->framebuffer.height = blit->saved.fb.height; 1136bf215546Sopenharmony_ci nvc0->framebuffer.samples = blit->saved.fb.samples; 1137bf215546Sopenharmony_ci nvc0->framebuffer.layers = blit->saved.fb.layers; 1138bf215546Sopenharmony_ci nvc0->framebuffer.nr_cbufs = blit->saved.fb.nr_cbufs; 1139bf215546Sopenharmony_ci nvc0->framebuffer.cbufs[0] = blit->saved.fb.cbufs[0]; 1140bf215546Sopenharmony_ci nvc0->framebuffer.zsbuf = blit->saved.fb.zsbuf; 1141bf215546Sopenharmony_ci 1142bf215546Sopenharmony_ci nvc0->rast = blit->saved.rast; 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_ci nvc0->vertprog = blit->saved.vp; 1145bf215546Sopenharmony_ci nvc0->tctlprog = blit->saved.tcp; 1146bf215546Sopenharmony_ci nvc0->tevlprog = blit->saved.tep; 1147bf215546Sopenharmony_ci nvc0->gmtyprog = blit->saved.gp; 1148bf215546Sopenharmony_ci nvc0->fragprog = blit->saved.fp; 1149bf215546Sopenharmony_ci 1150bf215546Sopenharmony_ci nvc0->min_samples = blit->saved.min_samples; 1151bf215546Sopenharmony_ci nvc0->window_rect = blit->saved.window_rect; 1152bf215546Sopenharmony_ci 1153bf215546Sopenharmony_ci pipe_sampler_view_reference(&nvc0->textures[4][0], NULL); 1154bf215546Sopenharmony_ci pipe_sampler_view_reference(&nvc0->textures[4][1], NULL); 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci for (s = 0; s <= 4; ++s) { 1157bf215546Sopenharmony_ci nvc0->num_textures[s] = blit->saved.num_textures[s]; 1158bf215546Sopenharmony_ci nvc0->num_samplers[s] = blit->saved.num_samplers[s]; 1159bf215546Sopenharmony_ci nvc0->textures_dirty[s] = (1 << nvc0->num_textures[s]) - 1; 1160bf215546Sopenharmony_ci nvc0->samplers_dirty[s] = (1 << nvc0->num_samplers[s]) - 1; 1161bf215546Sopenharmony_ci } 1162bf215546Sopenharmony_ci nvc0->textures[4][0] = blit->saved.texture[0]; 1163bf215546Sopenharmony_ci nvc0->textures[4][1] = blit->saved.texture[1]; 1164bf215546Sopenharmony_ci nvc0->samplers[4][0] = blit->saved.sampler[0]; 1165bf215546Sopenharmony_ci nvc0->samplers[4][1] = blit->saved.sampler[1]; 1166bf215546Sopenharmony_ci 1167bf215546Sopenharmony_ci nvc0->textures_dirty[4] |= 3; 1168bf215546Sopenharmony_ci nvc0->samplers_dirty[4] |= 3; 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_ci if (nvc0->cond_query && !blit->render_condition_enable) 1171bf215546Sopenharmony_ci nvc0->base.pipe.render_condition(&nvc0->base.pipe, nvc0->cond_query, 1172bf215546Sopenharmony_ci nvc0->cond_cond, nvc0->cond_mode); 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_VTX_TMP); 1175bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEXT); 1176bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB); 1177bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(4, 0)); 1178bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(4, 1)); 1179bf215546Sopenharmony_ci nouveau_scratch_done(&nvc0->base); 1180bf215546Sopenharmony_ci 1181bf215546Sopenharmony_ci nvc0->dirty_3d = blit->saved.dirty_3d | 1182bf215546Sopenharmony_ci (NVC0_NEW_3D_FRAMEBUFFER | NVC0_NEW_3D_SCISSOR | NVC0_NEW_3D_SAMPLE_MASK | 1183bf215546Sopenharmony_ci NVC0_NEW_3D_RASTERIZER | NVC0_NEW_3D_ZSA | NVC0_NEW_3D_BLEND | 1184bf215546Sopenharmony_ci NVC0_NEW_3D_VIEWPORT | NVC0_NEW_3D_WINDOW_RECTS | 1185bf215546Sopenharmony_ci NVC0_NEW_3D_TEXTURES | NVC0_NEW_3D_SAMPLERS | 1186bf215546Sopenharmony_ci NVC0_NEW_3D_VERTPROG | NVC0_NEW_3D_FRAGPROG | 1187bf215546Sopenharmony_ci NVC0_NEW_3D_TCTLPROG | NVC0_NEW_3D_TEVLPROG | NVC0_NEW_3D_GMTYPROG | 1188bf215546Sopenharmony_ci NVC0_NEW_3D_TFB_TARGETS | NVC0_NEW_3D_VERTEX | NVC0_NEW_3D_ARRAYS); 1189bf215546Sopenharmony_ci nvc0->scissors_dirty |= 1; 1190bf215546Sopenharmony_ci nvc0->viewports_dirty |= 1; 1191bf215546Sopenharmony_ci 1192bf215546Sopenharmony_ci nvc0->base.pipe.set_min_samples(&nvc0->base.pipe, blit->saved.min_samples); 1193bf215546Sopenharmony_ci} 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_cistatic void 1196bf215546Sopenharmony_cinvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) 1197bf215546Sopenharmony_ci{ 1198bf215546Sopenharmony_ci struct nvc0_screen *screen = nvc0->screen; 1199bf215546Sopenharmony_ci struct nvc0_blitctx *blit = nvc0->blit; 1200bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1201bf215546Sopenharmony_ci struct pipe_resource *src = info->src.resource; 1202bf215546Sopenharmony_ci struct pipe_resource *dst = info->dst.resource; 1203bf215546Sopenharmony_ci struct nouveau_bo *vtxbuf_bo; 1204bf215546Sopenharmony_ci uint32_t stride, length, *vbuf; 1205bf215546Sopenharmony_ci uint64_t vtxbuf; 1206bf215546Sopenharmony_ci int32_t minx, maxx, miny, maxy; 1207bf215546Sopenharmony_ci int32_t i, n; 1208bf215546Sopenharmony_ci float x0, x1, y0, y1, z; 1209bf215546Sopenharmony_ci float dz; 1210bf215546Sopenharmony_ci float x_range, y_range; 1211bf215546Sopenharmony_ci 1212bf215546Sopenharmony_ci blit->mode = nv50_blit_select_mode(info); 1213bf215546Sopenharmony_ci blit->color_mask = nv50_blit_derive_color_mask(info); 1214bf215546Sopenharmony_ci blit->filter = nv50_blit_get_filter(info); 1215bf215546Sopenharmony_ci blit->render_condition_enable = info->render_condition_enable; 1216bf215546Sopenharmony_ci 1217bf215546Sopenharmony_ci nvc0_blit_select_vp(blit); 1218bf215546Sopenharmony_ci nvc0_blit_select_fp(blit, info); 1219bf215546Sopenharmony_ci nvc0_blitctx_pre_blit(blit, info); 1220bf215546Sopenharmony_ci 1221bf215546Sopenharmony_ci nvc0_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format); 1222bf215546Sopenharmony_ci nvc0_blit_set_src(blit, src, info->src.level, -1, info->src.format, 1223bf215546Sopenharmony_ci blit->filter); 1224bf215546Sopenharmony_ci 1225bf215546Sopenharmony_ci nvc0_blitctx_prepare_state(blit); 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci nvc0_state_validate_3d(nvc0, ~0); 1228bf215546Sopenharmony_ci 1229bf215546Sopenharmony_ci x_range = (float)info->src.box.width / (float)info->dst.box.width; 1230bf215546Sopenharmony_ci y_range = (float)info->src.box.height / (float)info->dst.box.height; 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci x0 = (float)info->src.box.x - x_range * (float)info->dst.box.x; 1233bf215546Sopenharmony_ci y0 = (float)info->src.box.y - y_range * (float)info->dst.box.y; 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ci x1 = x0 + 32768.0f * x_range; 1236bf215546Sopenharmony_ci y1 = y0 + 32768.0f * y_range; 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci x0 *= (float)(1 << nv50_miptree(src)->ms_x); 1239bf215546Sopenharmony_ci x1 *= (float)(1 << nv50_miptree(src)->ms_x); 1240bf215546Sopenharmony_ci y0 *= (float)(1 << nv50_miptree(src)->ms_y); 1241bf215546Sopenharmony_ci y1 *= (float)(1 << nv50_miptree(src)->ms_y); 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci dz = (float)info->src.box.depth / (float)info->dst.box.depth; 1244bf215546Sopenharmony_ci z = (float)info->src.box.z; 1245bf215546Sopenharmony_ci if (nv50_miptree(src)->layout_3d) 1246bf215546Sopenharmony_ci z += 0.5f * dz; 1247bf215546Sopenharmony_ci 1248bf215546Sopenharmony_ci if (src->last_level > 0) { 1249bf215546Sopenharmony_ci /* If there are mip maps, GPU always assumes normalized coordinates. */ 1250bf215546Sopenharmony_ci const unsigned l = info->src.level; 1251bf215546Sopenharmony_ci const float fh = u_minify(src->width0 << nv50_miptree(src)->ms_x, l); 1252bf215546Sopenharmony_ci const float fv = u_minify(src->height0 << nv50_miptree(src)->ms_y, l); 1253bf215546Sopenharmony_ci x0 /= fh; 1254bf215546Sopenharmony_ci x1 /= fh; 1255bf215546Sopenharmony_ci y0 /= fv; 1256bf215546Sopenharmony_ci y1 /= fv; 1257bf215546Sopenharmony_ci if (nv50_miptree(src)->layout_3d) { 1258bf215546Sopenharmony_ci z /= u_minify(src->depth0, l); 1259bf215546Sopenharmony_ci dz /= u_minify(src->depth0, l); 1260bf215546Sopenharmony_ci } 1261bf215546Sopenharmony_ci } 1262bf215546Sopenharmony_ci 1263bf215546Sopenharmony_ci bool serialize = false; 1264bf215546Sopenharmony_ci struct nv50_miptree *mt = nv50_miptree(dst); 1265bf215546Sopenharmony_ci if (screen->eng3d->oclass >= TU102_3D_CLASS) { 1266bf215546Sopenharmony_ci IMMED_NVC0(push, SUBC_3D(TU102_3D_SET_COLOR_RENDER_TO_ZETA_SURFACE), 1267bf215546Sopenharmony_ci util_format_is_depth_or_stencil(info->dst.format)); 1268bf215546Sopenharmony_ci } else { 1269bf215546Sopenharmony_ci /* When flipping a surface from zeta <-> color "mode", we have to wait for 1270bf215546Sopenharmony_ci * the GPU to flush its current draws. 1271bf215546Sopenharmony_ci */ 1272bf215546Sopenharmony_ci serialize = util_format_is_depth_or_stencil(info->dst.format); 1273bf215546Sopenharmony_ci if (serialize && mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { 1274bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0); 1275bf215546Sopenharmony_ci } 1276bf215546Sopenharmony_ci } 1277bf215546Sopenharmony_ci 1278bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0); 1279bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 0x2 | 1280bf215546Sopenharmony_ci NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1); 1281bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); 1282bf215546Sopenharmony_ci PUSH_DATA (push, nvc0->framebuffer.width << 16); 1283bf215546Sopenharmony_ci PUSH_DATA (push, nvc0->framebuffer.height << 16); 1284bf215546Sopenharmony_ci 1285bf215546Sopenharmony_ci /* Draw a large triangle in screen coordinates covering the whole 1286bf215546Sopenharmony_ci * render target, with scissors defining the destination region. 1287bf215546Sopenharmony_ci * The vertex is supplied with non-normalized texture coordinates 1288bf215546Sopenharmony_ci * arranged in a way to yield the desired offset and scale. 1289bf215546Sopenharmony_ci * 1290bf215546Sopenharmony_ci * Note that while the source texture is presented to the sampler as 1291bf215546Sopenharmony_ci * non-MSAA (even if it is), the destination texture is treated as MSAA for 1292bf215546Sopenharmony_ci * rendering. This means that 1293bf215546Sopenharmony_ci * - destination coordinates shouldn't be scaled 1294bf215546Sopenharmony_ci * - without per-sample rendering, the target will be a solid-fill for all 1295bf215546Sopenharmony_ci * of the samples 1296bf215546Sopenharmony_ci * 1297bf215546Sopenharmony_ci * The last point implies that this process is very bad for 1:1 blits, as 1298bf215546Sopenharmony_ci * well as scaled blits between MSAA surfaces. This works fine for 1299bf215546Sopenharmony_ci * upscaling and downscaling though. The 1:1 blits should ideally be 1300bf215546Sopenharmony_ci * handled by the 2d engine, which can do it perfectly. 1301bf215546Sopenharmony_ci */ 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci minx = info->dst.box.x; 1304bf215546Sopenharmony_ci maxx = info->dst.box.x + info->dst.box.width; 1305bf215546Sopenharmony_ci miny = info->dst.box.y; 1306bf215546Sopenharmony_ci maxy = info->dst.box.y + info->dst.box.height; 1307bf215546Sopenharmony_ci if (info->scissor_enable) { 1308bf215546Sopenharmony_ci minx = MAX2(minx, info->scissor.minx); 1309bf215546Sopenharmony_ci maxx = MIN2(maxx, info->scissor.maxx); 1310bf215546Sopenharmony_ci miny = MAX2(miny, info->scissor.miny); 1311bf215546Sopenharmony_ci maxy = MIN2(maxy, info->scissor.maxy); 1312bf215546Sopenharmony_ci } 1313bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); 1314bf215546Sopenharmony_ci PUSH_DATA (push, (maxx << 16) | minx); 1315bf215546Sopenharmony_ci PUSH_DATA (push, (maxy << 16) | miny); 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ci stride = (3 + 2) * 4; 1318bf215546Sopenharmony_ci length = stride * 3 * info->dst.box.depth; 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ci vbuf = nouveau_scratch_get(&nvc0->base, length, &vtxbuf, &vtxbuf_bo); 1321bf215546Sopenharmony_ci if (!vbuf) { 1322bf215546Sopenharmony_ci assert(vbuf); 1323bf215546Sopenharmony_ci return; 1324bf215546Sopenharmony_ci } 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci BCTX_REFN_bo(nvc0->bufctx_3d, 3D_VTX_TMP, 1327bf215546Sopenharmony_ci NOUVEAU_BO_GART | NOUVEAU_BO_RD, vtxbuf_bo); 1328bf215546Sopenharmony_ci BCTX_REFN_bo(nvc0->bufctx_3d, 3D_TEXT, 1329bf215546Sopenharmony_ci NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD, screen->text); 1330bf215546Sopenharmony_ci nouveau_pushbuf_validate(push); 1331bf215546Sopenharmony_ci 1332bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(0)), 4); 1333bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE | stride << 1334bf215546Sopenharmony_ci NVC0_3D_VERTEX_ARRAY_FETCH_STRIDE__SHIFT); 1335bf215546Sopenharmony_ci PUSH_DATAh(push, vtxbuf); 1336bf215546Sopenharmony_ci PUSH_DATA (push, vtxbuf); 1337bf215546Sopenharmony_ci PUSH_DATA (push, 0); 1338bf215546Sopenharmony_ci if (screen->eng3d->oclass < TU102_3D_CLASS) 1339bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_LIMIT_HIGH(0)), 2); 1340bf215546Sopenharmony_ci else 1341bf215546Sopenharmony_ci BEGIN_NVC0(push, SUBC_3D(TU102_3D_VERTEX_ARRAY_LIMIT_HIGH(0)), 2); 1342bf215546Sopenharmony_ci PUSH_DATAh(push, vtxbuf + length - 1); 1343bf215546Sopenharmony_ci PUSH_DATA (push, vtxbuf + length - 1); 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci n = MAX2(2, nvc0->state.num_vtxelts); 1346bf215546Sopenharmony_ci 1347bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(0)), n); 1348bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT | 1349bf215546Sopenharmony_ci NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32_32 | 0x00 << 1350bf215546Sopenharmony_ci NVC0_3D_VERTEX_ATTRIB_FORMAT_OFFSET__SHIFT); 1351bf215546Sopenharmony_ci PUSH_DATA (push, NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT | 1352bf215546Sopenharmony_ci NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32_32_32 | 0x08 << 1353bf215546Sopenharmony_ci NVC0_3D_VERTEX_ATTRIB_FORMAT_OFFSET__SHIFT); 1354bf215546Sopenharmony_ci for (i = 2; i < n; i++) { 1355bf215546Sopenharmony_ci PUSH_DATA(push, NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT | 1356bf215546Sopenharmony_ci NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32 | 1357bf215546Sopenharmony_ci NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST); 1358bf215546Sopenharmony_ci } 1359bf215546Sopenharmony_ci for (i = 1; i < n; ++i) 1360bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 0); 1361bf215546Sopenharmony_ci if (nvc0->state.instance_elts) { 1362bf215546Sopenharmony_ci nvc0->state.instance_elts = 0; 1363bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(MACRO_VERTEX_ARRAY_PER_INSTANCE), 2); 1364bf215546Sopenharmony_ci PUSH_DATA (push, n); 1365bf215546Sopenharmony_ci PUSH_DATA (push, 0); 1366bf215546Sopenharmony_ci } 1367bf215546Sopenharmony_ci nvc0->state.num_vtxelts = 2; 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci if (nvc0->state.prim_restart) { 1370bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0); 1371bf215546Sopenharmony_ci nvc0->state.prim_restart = 0; 1372bf215546Sopenharmony_ci } 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_ci if (nvc0->state.index_bias) { 1375bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0); 1376bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VERTEX_ID_BASE), 0); 1377bf215546Sopenharmony_ci nvc0->state.index_bias = 0; 1378bf215546Sopenharmony_ci } 1379bf215546Sopenharmony_ci 1380bf215546Sopenharmony_ci for (i = 0; i < info->dst.box.depth; ++i, z += dz) { 1381bf215546Sopenharmony_ci if (info->dst.box.z + i) { 1382bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(LAYER), 1); 1383bf215546Sopenharmony_ci PUSH_DATA (push, info->dst.box.z + i); 1384bf215546Sopenharmony_ci } 1385bf215546Sopenharmony_ci 1386bf215546Sopenharmony_ci *(vbuf++) = fui(0.0f); 1387bf215546Sopenharmony_ci *(vbuf++) = fui(0.0f); 1388bf215546Sopenharmony_ci *(vbuf++) = fui(x0); 1389bf215546Sopenharmony_ci *(vbuf++) = fui(y0); 1390bf215546Sopenharmony_ci *(vbuf++) = fui(z); 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_ci *(vbuf++) = fui(32768.0f); 1393bf215546Sopenharmony_ci *(vbuf++) = fui(0.0f); 1394bf215546Sopenharmony_ci *(vbuf++) = fui(x1); 1395bf215546Sopenharmony_ci *(vbuf++) = fui(y0); 1396bf215546Sopenharmony_ci *(vbuf++) = fui(z); 1397bf215546Sopenharmony_ci 1398bf215546Sopenharmony_ci *(vbuf++) = fui(0.0f); 1399bf215546Sopenharmony_ci *(vbuf++) = fui(32768.0f); 1400bf215546Sopenharmony_ci *(vbuf++) = fui(x0); 1401bf215546Sopenharmony_ci *(vbuf++) = fui(y1); 1402bf215546Sopenharmony_ci *(vbuf++) = fui(z); 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1405bf215546Sopenharmony_ci NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); 1406bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2); 1407bf215546Sopenharmony_ci PUSH_DATA (push, i * 3); 1408bf215546Sopenharmony_ci PUSH_DATA (push, 3); 1409bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); 1410bf215546Sopenharmony_ci } 1411bf215546Sopenharmony_ci if (info->dst.box.z + info->dst.box.depth - 1) 1412bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(LAYER), 0); 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci nvc0_blitctx_post_blit(blit); 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci /* restore viewport transform */ 1417bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); 1418bf215546Sopenharmony_ci if (screen->eng3d->oclass >= TU102_3D_CLASS) 1419bf215546Sopenharmony_ci IMMED_NVC0(push, SUBC_3D(TU102_3D_SET_COLOR_RENDER_TO_ZETA_SURFACE), 0); 1420bf215546Sopenharmony_ci else if (serialize) 1421bf215546Sopenharmony_ci /* mark the surface as reading, which will force a serialize next time 1422bf215546Sopenharmony_ci * it's used for writing. 1423bf215546Sopenharmony_ci */ 1424bf215546Sopenharmony_ci mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_READING; 1425bf215546Sopenharmony_ci} 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_cistatic void 1428bf215546Sopenharmony_cinvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) 1429bf215546Sopenharmony_ci{ 1430bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1431bf215546Sopenharmony_ci struct nv50_miptree *dst = nv50_miptree(info->dst.resource); 1432bf215546Sopenharmony_ci struct nv50_miptree *src = nv50_miptree(info->src.resource); 1433bf215546Sopenharmony_ci const int32_t srcx_adj = info->src.box.width < 0 ? -1 : 0; 1434bf215546Sopenharmony_ci const int32_t srcy_adj = info->src.box.height < 0 ? -1 : 0; 1435bf215546Sopenharmony_ci const int dz = info->dst.box.z; 1436bf215546Sopenharmony_ci const int sz = info->src.box.z; 1437bf215546Sopenharmony_ci uint32_t dstw, dsth; 1438bf215546Sopenharmony_ci int32_t dstx, dsty; 1439bf215546Sopenharmony_ci int64_t srcx, srcy; 1440bf215546Sopenharmony_ci int64_t du_dx, dv_dy; 1441bf215546Sopenharmony_ci int i; 1442bf215546Sopenharmony_ci uint32_t mode; 1443bf215546Sopenharmony_ci uint32_t mask = nv50_blit_eng2d_get_mask(info); 1444bf215546Sopenharmony_ci bool b; 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ci mode = nv50_blit_get_filter(info) ? 1447bf215546Sopenharmony_ci NV50_2D_BLIT_CONTROL_FILTER_BILINEAR : 1448bf215546Sopenharmony_ci NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE; 1449bf215546Sopenharmony_ci mode |= (src->base.base.nr_samples > dst->base.base.nr_samples) ? 1450bf215546Sopenharmony_ci NV50_2D_BLIT_CONTROL_ORIGIN_CORNER : NV50_2D_BLIT_CONTROL_ORIGIN_CENTER; 1451bf215546Sopenharmony_ci 1452bf215546Sopenharmony_ci du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width; 1453bf215546Sopenharmony_ci dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height; 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci b = info->dst.format == info->src.format; 1456bf215546Sopenharmony_ci nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b); 1457bf215546Sopenharmony_ci nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b); 1458bf215546Sopenharmony_ci 1459bf215546Sopenharmony_ci if (info->scissor_enable) { 1460bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(CLIP_X), 5); 1461bf215546Sopenharmony_ci PUSH_DATA (push, info->scissor.minx << dst->ms_x); 1462bf215546Sopenharmony_ci PUSH_DATA (push, info->scissor.miny << dst->ms_y); 1463bf215546Sopenharmony_ci PUSH_DATA (push, (info->scissor.maxx - info->scissor.minx) << dst->ms_x); 1464bf215546Sopenharmony_ci PUSH_DATA (push, (info->scissor.maxy - info->scissor.miny) << dst->ms_y); 1465bf215546Sopenharmony_ci PUSH_DATA (push, 1); /* enable */ 1466bf215546Sopenharmony_ci } 1467bf215546Sopenharmony_ci 1468bf215546Sopenharmony_ci if (nvc0->cond_query && info->render_condition_enable) 1469bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(COND_MODE), nvc0->cond_condmode); 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci if (mask != 0xffffffff) { 1472bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(ROP), 0xca); /* DPSDxax */ 1473bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(PATTERN_COLOR_FORMAT), 1474bf215546Sopenharmony_ci NV50_2D_PATTERN_COLOR_FORMAT_A8R8G8B8); 1475bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(PATTERN_BITMAP_COLOR(0)), 4); 1476bf215546Sopenharmony_ci PUSH_DATA (push, 0x00000000); 1477bf215546Sopenharmony_ci PUSH_DATA (push, mask); 1478bf215546Sopenharmony_ci PUSH_DATA (push, 0xffffffff); 1479bf215546Sopenharmony_ci PUSH_DATA (push, 0xffffffff); 1480bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(OPERATION), NV50_2D_OPERATION_ROP); 1481bf215546Sopenharmony_ci } else 1482bf215546Sopenharmony_ci if (info->src.format != info->dst.format) { 1483bf215546Sopenharmony_ci if (info->src.format == PIPE_FORMAT_R8_UNORM || 1484bf215546Sopenharmony_ci info->src.format == PIPE_FORMAT_R8_SNORM || 1485bf215546Sopenharmony_ci info->src.format == PIPE_FORMAT_R16_UNORM || 1486bf215546Sopenharmony_ci info->src.format == PIPE_FORMAT_R16_SNORM || 1487bf215546Sopenharmony_ci info->src.format == PIPE_FORMAT_R16_FLOAT || 1488bf215546Sopenharmony_ci info->src.format == PIPE_FORMAT_R32_FLOAT) { 1489bf215546Sopenharmony_ci mask = 0xffff0000; /* also makes condition for OPERATION reset true */ 1490bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BETA4), 2); 1491bf215546Sopenharmony_ci PUSH_DATA (push, mask); 1492bf215546Sopenharmony_ci PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT); 1493bf215546Sopenharmony_ci } else 1494bf215546Sopenharmony_ci if (info->src.format == PIPE_FORMAT_A8_UNORM) { 1495bf215546Sopenharmony_ci mask = 0xff000000; 1496bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BETA4), 2); 1497bf215546Sopenharmony_ci PUSH_DATA (push, mask); 1498bf215546Sopenharmony_ci PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT); 1499bf215546Sopenharmony_ci } 1500bf215546Sopenharmony_ci } 1501bf215546Sopenharmony_ci 1502bf215546Sopenharmony_ci if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) { 1503bf215546Sopenharmony_ci /* ms_x is always >= ms_y */ 1504bf215546Sopenharmony_ci du_dx <<= src->ms_x - dst->ms_x; 1505bf215546Sopenharmony_ci dv_dy <<= src->ms_y - dst->ms_y; 1506bf215546Sopenharmony_ci } else { 1507bf215546Sopenharmony_ci du_dx >>= dst->ms_x - src->ms_x; 1508bf215546Sopenharmony_ci dv_dy >>= dst->ms_y - src->ms_y; 1509bf215546Sopenharmony_ci } 1510bf215546Sopenharmony_ci 1511bf215546Sopenharmony_ci srcx = (int64_t)(info->src.box.x + srcx_adj) << (src->ms_x + 32); 1512bf215546Sopenharmony_ci srcy = (int64_t)(info->src.box.y + srcy_adj) << (src->ms_y + 32); 1513bf215546Sopenharmony_ci 1514bf215546Sopenharmony_ci if (src->base.base.nr_samples > dst->base.base.nr_samples) { 1515bf215546Sopenharmony_ci /* center src coorinates for proper MS resolve filtering */ 1516bf215546Sopenharmony_ci srcx += (int64_t)1 << (src->ms_x + 31); 1517bf215546Sopenharmony_ci srcy += (int64_t)1 << (src->ms_y + 31); 1518bf215546Sopenharmony_ci } 1519bf215546Sopenharmony_ci 1520bf215546Sopenharmony_ci dstx = info->dst.box.x << dst->ms_x; 1521bf215546Sopenharmony_ci dsty = info->dst.box.y << dst->ms_y; 1522bf215546Sopenharmony_ci 1523bf215546Sopenharmony_ci dstw = info->dst.box.width << dst->ms_x; 1524bf215546Sopenharmony_ci dsth = info->dst.box.height << dst->ms_y; 1525bf215546Sopenharmony_ci 1526bf215546Sopenharmony_ci if (dstx < 0) { 1527bf215546Sopenharmony_ci dstw += dstx; 1528bf215546Sopenharmony_ci srcx -= du_dx * dstx; 1529bf215546Sopenharmony_ci dstx = 0; 1530bf215546Sopenharmony_ci } 1531bf215546Sopenharmony_ci if (dsty < 0) { 1532bf215546Sopenharmony_ci dsth += dsty; 1533bf215546Sopenharmony_ci srcy -= dv_dy * dsty; 1534bf215546Sopenharmony_ci dsty = 0; 1535bf215546Sopenharmony_ci } 1536bf215546Sopenharmony_ci 1537bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(BLIT_CONTROL), mode); 1538bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4); 1539bf215546Sopenharmony_ci PUSH_DATA (push, dstx); 1540bf215546Sopenharmony_ci PUSH_DATA (push, dsty); 1541bf215546Sopenharmony_ci PUSH_DATA (push, dstw); 1542bf215546Sopenharmony_ci PUSH_DATA (push, dsth); 1543bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4); 1544bf215546Sopenharmony_ci PUSH_DATA (push, du_dx); 1545bf215546Sopenharmony_ci PUSH_DATA (push, du_dx >> 32); 1546bf215546Sopenharmony_ci PUSH_DATA (push, dv_dy); 1547bf215546Sopenharmony_ci PUSH_DATA (push, dv_dy >> 32); 1548bf215546Sopenharmony_ci 1549bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx, 2D, &dst->base, WR); 1550bf215546Sopenharmony_ci BCTX_REFN(nvc0->bufctx, 2D, &src->base, RD); 1551bf215546Sopenharmony_ci nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx); 1552bf215546Sopenharmony_ci if (nouveau_pushbuf_validate(nvc0->base.pushbuf)) 1553bf215546Sopenharmony_ci return; 1554bf215546Sopenharmony_ci 1555bf215546Sopenharmony_ci for (i = 0; i < info->dst.box.depth; ++i) { 1556bf215546Sopenharmony_ci if (i > 0) { 1557bf215546Sopenharmony_ci /* no scaling in z-direction possible for eng2d blits */ 1558bf215546Sopenharmony_ci if (dst->layout_3d) { 1559bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(DST_LAYER), 1); 1560bf215546Sopenharmony_ci PUSH_DATA (push, info->dst.box.z + i); 1561bf215546Sopenharmony_ci } else { 1562bf215546Sopenharmony_ci const unsigned z = info->dst.box.z + i; 1563bf215546Sopenharmony_ci const uint64_t address = dst->base.address + 1564bf215546Sopenharmony_ci dst->level[info->dst.level].offset + 1565bf215546Sopenharmony_ci z * dst->layer_stride; 1566bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(DST_ADDRESS_HIGH), 2); 1567bf215546Sopenharmony_ci PUSH_DATAh(push, address); 1568bf215546Sopenharmony_ci PUSH_DATA (push, address); 1569bf215546Sopenharmony_ci } 1570bf215546Sopenharmony_ci if (src->layout_3d) { 1571bf215546Sopenharmony_ci /* not possible because of depth tiling */ 1572bf215546Sopenharmony_ci assert(0); 1573bf215546Sopenharmony_ci } else { 1574bf215546Sopenharmony_ci const unsigned z = info->src.box.z + i; 1575bf215546Sopenharmony_ci const uint64_t address = src->base.address + 1576bf215546Sopenharmony_ci src->level[info->src.level].offset + 1577bf215546Sopenharmony_ci z * src->layer_stride; 1578bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(SRC_ADDRESS_HIGH), 2); 1579bf215546Sopenharmony_ci PUSH_DATAh(push, address); 1580bf215546Sopenharmony_ci PUSH_DATA (push, address); 1581bf215546Sopenharmony_ci } 1582bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_Y_INT), 1); /* trigger */ 1583bf215546Sopenharmony_ci PUSH_DATA (push, srcy >> 32); 1584bf215546Sopenharmony_ci } else { 1585bf215546Sopenharmony_ci BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4); 1586bf215546Sopenharmony_ci PUSH_DATA (push, srcx); 1587bf215546Sopenharmony_ci PUSH_DATA (push, srcx >> 32); 1588bf215546Sopenharmony_ci PUSH_DATA (push, srcy); 1589bf215546Sopenharmony_ci PUSH_DATA (push, srcy >> 32); 1590bf215546Sopenharmony_ci } 1591bf215546Sopenharmony_ci } 1592bf215546Sopenharmony_ci nvc0_resource_validate(&dst->base, NOUVEAU_BO_WR); 1593bf215546Sopenharmony_ci nvc0_resource_validate(&src->base, NOUVEAU_BO_RD); 1594bf215546Sopenharmony_ci 1595bf215546Sopenharmony_ci nouveau_bufctx_reset(nvc0->bufctx, NVC0_BIND_2D); 1596bf215546Sopenharmony_ci 1597bf215546Sopenharmony_ci if (info->scissor_enable) 1598bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(CLIP_ENABLE), 0); 1599bf215546Sopenharmony_ci if (mask != 0xffffffff) 1600bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(OPERATION), NV50_2D_OPERATION_SRCCOPY); 1601bf215546Sopenharmony_ci if (nvc0->cond_query && info->render_condition_enable) 1602bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_2D(COND_MODE), NV50_2D_COND_MODE_ALWAYS); 1603bf215546Sopenharmony_ci} 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_cistatic void 1606bf215546Sopenharmony_cinvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) 1607bf215546Sopenharmony_ci{ 1608bf215546Sopenharmony_ci struct nvc0_context *nvc0 = nvc0_context(pipe); 1609bf215546Sopenharmony_ci struct nouveau_pushbuf *push = nvc0->base.pushbuf; 1610bf215546Sopenharmony_ci bool eng3d = false; 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_ci if (info->src.box.width == 0 || info->src.box.height == 0 || 1613bf215546Sopenharmony_ci info->dst.box.width == 0 || info->dst.box.height == 0) { 1614bf215546Sopenharmony_ci util_debug_message(&nvc0->base.debug, ERROR, 1615bf215546Sopenharmony_ci "Blit with zero-size src or dst box"); 1616bf215546Sopenharmony_ci return; 1617bf215546Sopenharmony_ci } 1618bf215546Sopenharmony_ci 1619bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(info->dst.resource->format)) { 1620bf215546Sopenharmony_ci if (!(info->mask & PIPE_MASK_ZS)) 1621bf215546Sopenharmony_ci return; 1622bf215546Sopenharmony_ci if (info->dst.resource->format == PIPE_FORMAT_Z32_FLOAT || 1623bf215546Sopenharmony_ci info->dst.resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) 1624bf215546Sopenharmony_ci eng3d = true; 1625bf215546Sopenharmony_ci if (info->filter != PIPE_TEX_FILTER_NEAREST) 1626bf215546Sopenharmony_ci eng3d = true; 1627bf215546Sopenharmony_ci } else { 1628bf215546Sopenharmony_ci if (!(info->mask & PIPE_MASK_RGBA)) 1629bf215546Sopenharmony_ci return; 1630bf215546Sopenharmony_ci if (info->mask != PIPE_MASK_RGBA) 1631bf215546Sopenharmony_ci eng3d = true; 1632bf215546Sopenharmony_ci } 1633bf215546Sopenharmony_ci 1634bf215546Sopenharmony_ci if (nv50_miptree(info->src.resource)->layout_3d) { 1635bf215546Sopenharmony_ci eng3d = true; 1636bf215546Sopenharmony_ci } else 1637bf215546Sopenharmony_ci if (info->src.box.depth != info->dst.box.depth) { 1638bf215546Sopenharmony_ci eng3d = true; 1639bf215546Sopenharmony_ci debug_printf("blit: cannot filter array or cube textures in z direction"); 1640bf215546Sopenharmony_ci } 1641bf215546Sopenharmony_ci 1642bf215546Sopenharmony_ci if (!eng3d && info->dst.format != info->src.format) { 1643bf215546Sopenharmony_ci if (!nv50_2d_dst_format_faithful(info->dst.format)) { 1644bf215546Sopenharmony_ci eng3d = true; 1645bf215546Sopenharmony_ci } else 1646bf215546Sopenharmony_ci if (!nv50_2d_src_format_faithful(info->src.format)) { 1647bf215546Sopenharmony_ci if (!util_format_is_luminance(info->src.format)) { 1648bf215546Sopenharmony_ci if (!nv50_2d_dst_format_ops_supported(info->dst.format)) 1649bf215546Sopenharmony_ci eng3d = true; 1650bf215546Sopenharmony_ci else 1651bf215546Sopenharmony_ci if (util_format_is_intensity(info->src.format)) 1652bf215546Sopenharmony_ci eng3d = info->src.format != PIPE_FORMAT_I8_UNORM; 1653bf215546Sopenharmony_ci else 1654bf215546Sopenharmony_ci if (util_format_is_alpha(info->src.format)) 1655bf215546Sopenharmony_ci eng3d = info->src.format != PIPE_FORMAT_A8_UNORM; 1656bf215546Sopenharmony_ci else 1657bf215546Sopenharmony_ci if (util_format_is_srgb(info->dst.format) && 1658bf215546Sopenharmony_ci util_format_get_nr_components(info->src.format) == 1) 1659bf215546Sopenharmony_ci eng3d = true; 1660bf215546Sopenharmony_ci else 1661bf215546Sopenharmony_ci eng3d = !nv50_2d_format_supported(info->src.format); 1662bf215546Sopenharmony_ci } 1663bf215546Sopenharmony_ci } else 1664bf215546Sopenharmony_ci if (util_format_is_luminance_alpha(info->src.format)) 1665bf215546Sopenharmony_ci eng3d = true; 1666bf215546Sopenharmony_ci } 1667bf215546Sopenharmony_ci 1668bf215546Sopenharmony_ci if (info->src.resource->nr_samples == 8 && 1669bf215546Sopenharmony_ci info->dst.resource->nr_samples <= 1) 1670bf215546Sopenharmony_ci eng3d = true; 1671bf215546Sopenharmony_ci#if 0 1672bf215546Sopenharmony_ci /* FIXME: can't make this work with eng2d anymore, at least not on nv50 */ 1673bf215546Sopenharmony_ci if (info->src.resource->nr_samples > 1 || 1674bf215546Sopenharmony_ci info->dst.resource->nr_samples > 1) 1675bf215546Sopenharmony_ci eng3d = true; 1676bf215546Sopenharmony_ci#endif 1677bf215546Sopenharmony_ci /* FIXME: find correct src coordinates adjustments */ 1678bf215546Sopenharmony_ci if ((info->src.box.width != info->dst.box.width && 1679bf215546Sopenharmony_ci info->src.box.width != -info->dst.box.width) || 1680bf215546Sopenharmony_ci (info->src.box.height != info->dst.box.height && 1681bf215546Sopenharmony_ci info->src.box.height != -info->dst.box.height)) 1682bf215546Sopenharmony_ci eng3d = true; 1683bf215546Sopenharmony_ci 1684bf215546Sopenharmony_ci if (info->num_window_rectangles > 0 || info->window_rectangle_include) 1685bf215546Sopenharmony_ci eng3d = true; 1686bf215546Sopenharmony_ci 1687bf215546Sopenharmony_ci if (nvc0->screen->num_occlusion_queries_active) 1688bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0); 1689bf215546Sopenharmony_ci 1690bf215546Sopenharmony_ci if (!eng3d) 1691bf215546Sopenharmony_ci nvc0_blit_eng2d(nvc0, info); 1692bf215546Sopenharmony_ci else 1693bf215546Sopenharmony_ci nvc0_blit_3d(nvc0, info); 1694bf215546Sopenharmony_ci 1695bf215546Sopenharmony_ci if (nvc0->screen->num_occlusion_queries_active) 1696bf215546Sopenharmony_ci IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1); 1697bf215546Sopenharmony_ci 1698bf215546Sopenharmony_ci NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_blit_count, 1); 1699bf215546Sopenharmony_ci} 1700bf215546Sopenharmony_ci 1701bf215546Sopenharmony_cistatic void 1702bf215546Sopenharmony_cinvc0_flush_resource(struct pipe_context *ctx, 1703bf215546Sopenharmony_ci struct pipe_resource *resource) 1704bf215546Sopenharmony_ci{ 1705bf215546Sopenharmony_ci} 1706bf215546Sopenharmony_ci 1707bf215546Sopenharmony_cibool 1708bf215546Sopenharmony_cinvc0_blitter_create(struct nvc0_screen *screen) 1709bf215546Sopenharmony_ci{ 1710bf215546Sopenharmony_ci screen->blitter = CALLOC_STRUCT(nvc0_blitter); 1711bf215546Sopenharmony_ci if (!screen->blitter) { 1712bf215546Sopenharmony_ci NOUVEAU_ERR("failed to allocate blitter struct\n"); 1713bf215546Sopenharmony_ci return false; 1714bf215546Sopenharmony_ci } 1715bf215546Sopenharmony_ci screen->blitter->screen = screen; 1716bf215546Sopenharmony_ci 1717bf215546Sopenharmony_ci (void) mtx_init(&screen->blitter->mutex, mtx_plain); 1718bf215546Sopenharmony_ci 1719bf215546Sopenharmony_ci nvc0_blitter_make_sampler(screen->blitter); 1720bf215546Sopenharmony_ci 1721bf215546Sopenharmony_ci return true; 1722bf215546Sopenharmony_ci} 1723bf215546Sopenharmony_ci 1724bf215546Sopenharmony_civoid 1725bf215546Sopenharmony_cinvc0_blitter_destroy(struct nvc0_screen *screen) 1726bf215546Sopenharmony_ci{ 1727bf215546Sopenharmony_ci struct nvc0_blitter *blitter = screen->blitter; 1728bf215546Sopenharmony_ci unsigned i, m; 1729bf215546Sopenharmony_ci 1730bf215546Sopenharmony_ci for (i = 0; i < NV50_BLIT_MAX_TEXTURE_TYPES; ++i) { 1731bf215546Sopenharmony_ci for (m = 0; m < NV50_BLIT_MODES; ++m) { 1732bf215546Sopenharmony_ci struct nvc0_program *prog = blitter->fp[i][m]; 1733bf215546Sopenharmony_ci if (prog) { 1734bf215546Sopenharmony_ci nvc0_program_destroy(NULL, prog); 1735bf215546Sopenharmony_ci FREE((void *)prog->pipe.tokens); 1736bf215546Sopenharmony_ci FREE(prog); 1737bf215546Sopenharmony_ci } 1738bf215546Sopenharmony_ci } 1739bf215546Sopenharmony_ci } 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_ci mtx_destroy(&blitter->mutex); 1742bf215546Sopenharmony_ci FREE(blitter); 1743bf215546Sopenharmony_ci} 1744bf215546Sopenharmony_ci 1745bf215546Sopenharmony_cibool 1746bf215546Sopenharmony_cinvc0_blitctx_create(struct nvc0_context *nvc0) 1747bf215546Sopenharmony_ci{ 1748bf215546Sopenharmony_ci nvc0->blit = CALLOC_STRUCT(nvc0_blitctx); 1749bf215546Sopenharmony_ci if (!nvc0->blit) { 1750bf215546Sopenharmony_ci NOUVEAU_ERR("failed to allocate blit context\n"); 1751bf215546Sopenharmony_ci return false; 1752bf215546Sopenharmony_ci } 1753bf215546Sopenharmony_ci 1754bf215546Sopenharmony_ci nvc0->blit->nvc0 = nvc0; 1755bf215546Sopenharmony_ci 1756bf215546Sopenharmony_ci nvc0->blit->rast.pipe.half_pixel_center = 1; 1757bf215546Sopenharmony_ci 1758bf215546Sopenharmony_ci return true; 1759bf215546Sopenharmony_ci} 1760bf215546Sopenharmony_ci 1761bf215546Sopenharmony_civoid 1762bf215546Sopenharmony_cinvc0_blitctx_destroy(struct nvc0_context *nvc0) 1763bf215546Sopenharmony_ci{ 1764bf215546Sopenharmony_ci FREE(nvc0->blit); 1765bf215546Sopenharmony_ci} 1766bf215546Sopenharmony_ci 1767bf215546Sopenharmony_civoid 1768bf215546Sopenharmony_cinvc0_init_surface_functions(struct nvc0_context *nvc0) 1769bf215546Sopenharmony_ci{ 1770bf215546Sopenharmony_ci struct pipe_context *pipe = &nvc0->base.pipe; 1771bf215546Sopenharmony_ci 1772bf215546Sopenharmony_ci pipe->resource_copy_region = nvc0_resource_copy_region; 1773bf215546Sopenharmony_ci pipe->blit = nvc0_blit; 1774bf215546Sopenharmony_ci pipe->flush_resource = nvc0_flush_resource; 1775bf215546Sopenharmony_ci pipe->clear_render_target = nvc0_clear_render_target; 1776bf215546Sopenharmony_ci pipe->clear_depth_stencil = nvc0_clear_depth_stencil; 1777bf215546Sopenharmony_ci pipe->clear_texture = nv50_clear_texture; 1778bf215546Sopenharmony_ci pipe->clear_buffer = nvc0_clear_buffer; 1779bf215546Sopenharmony_ci if (nvc0->screen->base.class_3d >= GM200_3D_CLASS) 1780bf215546Sopenharmony_ci pipe->evaluate_depth_buffer = gm200_evaluate_depth_buffer; 1781bf215546Sopenharmony_ci} 1782