static int nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push, struct nv50_miptree *dst, unsigned dst_level, unsigned dx, unsigned dy, unsigned dz, struct nv50_miptree *src, unsigned src_level, unsigned sx, unsigned sy, unsigned sz, unsigned w, unsigned h) { static const uint32_t duvdxy[5] = { 0x40000000, 0x80000000, 0x00000001, 0x00000002, 0x00000004 }; int ret; uint32_t ctrl = 0x00; ret = PUSH_SPACE(push, 2 * 16 + 32); if (ret) return ret; ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz); if (ret) return ret; ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz); if (ret) return ret; /* NOTE: 2D engine doesn't work for MS8 */ if (src->ms_x) ctrl = 0x11; /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */ BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1); PUSH_DATA (push, ctrl); BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4); PUSH_DATA (push, dx << dst->ms_x); PUSH_DATA (push, dy << dst->ms_y); PUSH_DATA (push, w << dst->ms_x); PUSH_DATA (push, h << dst->ms_y); BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4); PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4); PUSH_DATA (push, 0); PUSH_DATA (push, sx << src->ms_x); PUSH_DATA (push, 0); PUSH_DATA (push, sy << src->ms_x); return 0; }
static int nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push, struct nv50_miptree *dst, unsigned dst_level, unsigned dx, unsigned dy, unsigned dz, struct nv50_miptree *src, unsigned src_level, unsigned sx, unsigned sy, unsigned sz, unsigned w, unsigned h) { const enum pipe_format dfmt = dst->base.base.format; const enum pipe_format sfmt = src->base.base.format; int ret; boolean eqfmt = dfmt == sfmt; if (!PUSH_SPACE(push, 2 * 16 + 32)) return PIPE_ERROR; ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt, eqfmt); if (ret) return ret; ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt, eqfmt); if (ret) return ret; IMMED_NVC0(push, NVC0_2D(BLIT_CONTROL), 0x00); BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4); PUSH_DATA (push, dx << dst->ms_x); PUSH_DATA (push, dy << dst->ms_y); PUSH_DATA (push, w << dst->ms_x); PUSH_DATA (push, h << dst->ms_y); BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4); PUSH_DATA (push, 0); PUSH_DATA (push, 1); PUSH_DATA (push, 0); PUSH_DATA (push, 1); BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4); PUSH_DATA (push, 0); PUSH_DATA (push, sx << src->ms_x); PUSH_DATA (push, 0); PUSH_DATA (push, sy << src->ms_x); return 0; }
static void nvc0_render_condition(struct pipe_context *pipe, struct pipe_query *pq, boolean condition, uint mode) { struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_query *q = nvc0_query(pq); struct nvc0_hw_query *hq = nvc0_hw_query(q); uint32_t cond; bool wait = mode != PIPE_RENDER_COND_NO_WAIT && mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT; if (!pq) { cond = NVC0_3D_COND_MODE_ALWAYS; } else { /* NOTE: comparison of 2 queries only works if both have completed */ switch (q->type) { case PIPE_QUERY_SO_OVERFLOW_PREDICATE: cond = condition ? NVC0_3D_COND_MODE_EQUAL : NVC0_3D_COND_MODE_NOT_EQUAL; wait = true; break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: if (likely(!condition)) { if (unlikely(hq->nesting)) cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL : NVC0_3D_COND_MODE_ALWAYS; else cond = NVC0_3D_COND_MODE_RES_NON_ZERO; } else { cond = wait ? NVC0_3D_COND_MODE_EQUAL : NVC0_3D_COND_MODE_ALWAYS; } break; default: assert(!"render condition query not a predicate"); cond = NVC0_3D_COND_MODE_ALWAYS; break; } } nvc0->cond_query = pq; nvc0->cond_cond = condition; nvc0->cond_condmode = cond; nvc0->cond_mode = mode; if (!pq) { PUSH_SPACE(push, 1); IMMED_NVC0(push, NVC0_3D(COND_MODE), cond); return; } if (wait) nvc0_hw_query_fifo_wait(nvc0, q); PUSH_SPACE(push, 7); PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3); PUSH_DATAh(push, hq->bo->offset + hq->offset); PUSH_DATA (push, hq->bo->offset + hq->offset); PUSH_DATA (push, cond); BEGIN_NVC0(push, NVC0_2D(COND_ADDRESS_HIGH), 2); PUSH_DATAh(push, hq->bo->offset + hq->offset); PUSH_DATA (push, hq->bo->offset + hq->offset); }