static void
nv10_clear(struct gl_context *ctx, GLbitfield buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);

	nouveau_validate_framebuffer(ctx);

	nouveau_pushbuf_bufctx(push, nctx->hw.bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return;
	}

	if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask) {
		if (context_chipset(ctx) >= 0x17)
			nv17_zclear(ctx, &buffers);
		else
			nv10_zclear(ctx, &buffers);

		/* Emit the zclear state if it's dirty */
		_mesa_update_state(ctx);
	}

	nouveau_pushbuf_bufctx(push, NULL);
	nouveau_clear(ctx, buffers);
}
static void
nv20_clear(struct gl_context *ctx, GLbitfield buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;
	uint32_t clear = 0;

	nouveau_validate_framebuffer(ctx);

	nouveau_pushbuf_bufctx(push, nctx->hw.bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return;
	}

	if (buffers & BUFFER_BITS_COLOR) {
		struct nouveau_surface *s = &to_nouveau_renderbuffer(
			fb->_ColorDrawBuffers[0])->surface;

		if (ctx->Color.ColorMask[0][RCOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_R;
		if (ctx->Color.ColorMask[0][GCOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_G;
		if (ctx->Color.ColorMask[0][BCOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_B;
		if (ctx->Color.ColorMask[0][ACOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_A;

		BEGIN_NV04(push, NV20_3D(CLEAR_VALUE), 1);
		PUSH_DATA (push, pack_rgba_clamp_f(s->format, ctx->Color.ClearColor.f));

		buffers &= ~BUFFER_BITS_COLOR;
	}

	if (buffers & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
		struct nouveau_surface *s = &to_nouveau_renderbuffer(
			fb->Attachment[BUFFER_DEPTH].Renderbuffer)->surface;

		if (buffers & BUFFER_BIT_DEPTH && ctx->Depth.Mask)
			clear |= NV20_3D_CLEAR_BUFFERS_DEPTH;
		if (buffers & BUFFER_BIT_STENCIL && ctx->Stencil.WriteMask[0])
			clear |= NV20_3D_CLEAR_BUFFERS_STENCIL;

		BEGIN_NV04(push, NV20_3D(CLEAR_DEPTH_VALUE), 1);
		PUSH_DATA (push, pack_zs_f(s->format, ctx->Depth.Clear,
					 ctx->Stencil.Clear));

		buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
	}

	BEGIN_NV04(push, NV20_3D(CLEAR_BUFFERS), 1);
	PUSH_DATA (push, clear);

	nouveau_pushbuf_bufctx(push, NULL);
	nouveau_clear(ctx, buffers);
}
Bool
NV10EXAPrepareComposite(int op,
			PicturePtr pict_src,
			PicturePtr pict_mask,
			PicturePtr pict_dst,
			PixmapPtr src,
			PixmapPtr mask,
			PixmapPtr dst)
{
	ScrnInfoPtr pScrn = xf86ScreenToScrn(dst->drawable.pScreen);
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	uint32_t sc, sa, mc, ma;

	if (!PUSH_SPACE(push, 128))
		return FALSE;
	PUSH_RESET(push);

	/* setup render target and blending */
	if (!setup_render_target(pNv, pict_dst, dst))
		return FALSE;
	setup_blend_function(pNv, pict_dst, op);

	/* select picture sources */
	if (!setup_picture(pNv, pict_src, src, 0, &sc, &sa))
		return FALSE;
	if (!setup_picture(pNv, pict_mask, mask, 1, &mc, &ma))
		return FALSE;

	/* configure register combiners */
	BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(0)), 1);
	PUSH_DATA (push, sa | ma);
	BEGIN_NV04(push, NV10_3D(RC_IN_RGB(0)), 1);
	if (effective_component_alpha(pict_mask)) {
		if (needs_src_alpha(op))
			PUSH_DATA(push, sa | mc);
		else
			PUSH_DATA(push, sc | mc);
	} else {
		PUSH_DATA(push, sc | ma);
	}

	nouveau_pushbuf_bufctx(push, pNv->bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return FALSE;
	}

	pNv->pspict = pict_src;
	pNv->pmpict = pict_mask;
	return TRUE;
}
static void
nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
{
   struct nv50_screen *screen = nv50->screen;
   struct nouveau_pushbuf *push = screen->base.pushbuf;
   unsigned size = align(nv50->compprog->parm_size, 0x4);

   BEGIN_NV04(push, NV50_COMPUTE(USER_PARAM_COUNT), 1);
   PUSH_DATA (push, (size / 4) << 8);

   if (size) {
      struct nouveau_mm_allocation *mm;
      struct nouveau_bo *bo = NULL;
      unsigned offset;

      mm = nouveau_mm_allocate(screen->base.mm_GART, size, &bo, &offset);
      assert(mm);

      nouveau_bo_map(bo, 0, screen->base.client);
      memcpy(bo->map + offset, input, size);

      nouveau_bufctx_refn(nv50->bufctx, 0, bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
      nouveau_pushbuf_bufctx(push, nv50->bufctx);
      nouveau_pushbuf_validate(push);

      BEGIN_NV04(push, NV50_COMPUTE(USER_PARAM(0)), size / 4);
      nouveau_pushbuf_data(push, bo, offset, size);

      nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, mm);
      nouveau_bo_ref(NULL, &bo);
      nouveau_bufctx_reset(nv50->bufctx, 0);
   }
}
Exemple #5
0
static void
nvc0_destroy(struct pipe_context *pipe)
{
   struct nvc0_context *nvc0 = nvc0_context(pipe);

   if (nvc0->screen->cur_ctx == nvc0) {
      nvc0->screen->cur_ctx = NULL;
      nvc0->screen->save_state = nvc0->state;
      nvc0->screen->save_state.tfb = NULL;
   }

   if (nvc0->base.pipe.stream_uploader)
      u_upload_destroy(nvc0->base.pipe.stream_uploader);

   /* Unset bufctx, we don't want to revalidate any resources after the flush.
    * Other contexts will always set their bufctx again on action calls.
    */
   nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
   nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);

   nvc0_context_unreference_resources(nvc0);
   nvc0_blitctx_destroy(nvc0);

   nouveau_context_destroy(&nvc0->base);
}
Exemple #6
0
static void
nve4_m2mf_copy_linear(struct nouveau_context *nv,
                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
                      unsigned size)
{
   struct nouveau_pushbuf *push = nv->pushbuf;
   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;

   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
   nouveau_pushbuf_bufctx(push, bctx);
   nouveau_pushbuf_validate(push);

   BEGIN_NVC0(push, SUBC_COPY(0x0400), 4);
   PUSH_DATAh(push, src->offset + srcoff);
   PUSH_DATA (push, src->offset + srcoff);
   PUSH_DATAh(push, dst->offset + dstoff);
   PUSH_DATA (push, dst->offset + dstoff);
   BEGIN_NVC0(push, SUBC_COPY(0x0418), 1);
   PUSH_DATA (push, size);
   BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
   PUSH_DATA (push, 0x186);

   nouveau_bufctx_reset(bctx, 0);
}
Exemple #7
0
void
nvc0_m2mf_push_linear(struct nouveau_context *nv,
                      struct nouveau_bo *dst, unsigned offset, unsigned domain,
                      unsigned size, const void *data)
{
   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
   struct nouveau_pushbuf *push = nv->pushbuf;
   uint32_t *src = (uint32_t *)data;
   unsigned count = (size + 3) / 4;

   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
   nouveau_pushbuf_validate(push);

   while (count) {
      unsigned nr;

      if (!PUSH_SPACE(push, 16))
         break;
      nr = PUSH_AVAIL(push);
      assert(nr >= 16);
      nr = MIN2(count, nr - 9);
      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);

      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
      PUSH_DATAh(push, dst->offset + offset);
      PUSH_DATA (push, dst->offset + offset);
      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
      PUSH_DATA (push, MIN2(size, nr * 4));
      PUSH_DATA (push, 1);
      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
      PUSH_DATA (push, 0x100111);

      /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
      BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);
      PUSH_DATAp(push, src, nr);

      count -= nr;
      src += nr;
      offset += nr * 4;
      size -= nr * 4;
   }

   nouveau_bufctx_reset(nvc0->bufctx, 0);
}
Exemple #8
0
static boolean
nvc0_compute_state_validate(struct nvc0_context *nvc0)
{
   if (!nvc0_compute_validate_program(nvc0))
      return FALSE;

   /* TODO: textures, samplers, surfaces, global memory buffers */

   nvc0_bufctx_fence(nvc0, nvc0->bufctx_cp, FALSE);

   nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx_cp);
   if (unlikely(nouveau_pushbuf_validate(nvc0->base.pushbuf)))
      return FALSE;
   if (unlikely(nvc0->state.flushed))
      nvc0_bufctx_fence(nvc0, nvc0->bufctx_cp, TRUE);

   return TRUE;

}
Exemple #9
0
static void
nv50_destroy(struct pipe_context *pipe)
{
   struct nv50_context *nv50 = nv50_context(pipe);

   if (nv50->screen->cur_ctx == nv50) {
      nv50->screen->cur_ctx = NULL;
      /* Save off the state in case another context gets created */
      nv50->screen->save_state = nv50->state;
   }
   nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
   nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);

   nv50_context_unreference_resources(nv50);

   FREE(nv50->blit);

   nouveau_context_destroy(&nv50->base);
}
Exemple #10
0
static void
nvc0_destroy(struct pipe_context *pipe)
{
   struct nvc0_context *nvc0 = nvc0_context(pipe);

   if (nvc0->screen->cur_ctx == nvc0) {
      nvc0->base.pushbuf->kick_notify = NULL;
      nvc0->screen->cur_ctx = NULL;
      nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
   }
   nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);

   nvc0_context_unreference_resources(nvc0);

#ifdef NVC0_WITH_DRAW_MODULE
   draw_destroy(nvc0->draw);
#endif

   nouveau_context_destroy(&nvc0->base);
}
static bool
nv50_compute_state_validate(struct nv50_context *nv50)
{
   if (!nv50_compute_validate_program(nv50))
      return false;

   if (nv50->dirty_cp & NV50_NEW_CP_GLOBALS)
      nv50_compute_validate_globals(nv50);

   /* TODO: validate textures, samplers, surfaces */

   nv50_bufctx_fence(nv50->bufctx_cp, false);

   nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_cp);
   if (unlikely(nouveau_pushbuf_validate(nv50->base.pushbuf)))
      return false;
   if (unlikely(nv50->state.flushed))
      nv50_bufctx_fence(nv50->bufctx_cp, true);

   return true;
}
Exemple #12
0
static void
nv50_destroy(struct pipe_context *pipe)
{
   struct nv50_context *nv50 = nv50_context(pipe);

   if (nv50_context_screen(nv50)->cur_ctx == nv50) {
      nv50->base.pushbuf->kick_notify = NULL;
      nv50_context_screen(nv50)->cur_ctx = NULL;
      nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
   }
   /* need to flush before destroying the bufctx */
   nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);

   nv50_context_unreference_resources(nv50);

#ifdef NV50_WITH_DRAW_MODULE
   draw_destroy(nv50->draw);
#endif

   nouveau_context_destroy(&nv50->base);
}
void
nvc0_cb_push(struct nouveau_context *nv,
             struct nouveau_bo *bo, unsigned domain,
             unsigned base, unsigned size,
             unsigned offset, unsigned words, const uint32_t *data)
{
   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
   struct nouveau_pushbuf *push = nv->pushbuf;

   NOUVEAU_DRV_STAT(nv->screen, constbuf_upload_count, 1);
   NOUVEAU_DRV_STAT(nv->screen, constbuf_upload_bytes, words * 4);

   assert(!(offset & 3));
   size = align(size, 0x100);

   nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
   nouveau_pushbuf_bufctx(push, bctx);
   nouveau_pushbuf_validate(push);

   BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
   PUSH_DATA (push, size);
   PUSH_DATAh(push, bo->offset + base);
   PUSH_DATA (push, bo->offset + base);

   while (words) {
      unsigned nr = PUSH_AVAIL(push);
      nr = MIN2(nr, words);
      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);

      BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
      PUSH_DATA (push, offset);
      PUSH_DATAp(push, data, nr);

      words -= nr;
      data += nr;
      offset += nr * 4;
   }

   nouveau_bufctx_reset(bctx, 0);
}
Exemple #14
0
static void
nvc0_destroy(struct pipe_context *pipe)
{
   struct nvc0_context *nvc0 = nvc0_context(pipe);

   if (nvc0->screen->cur_ctx == nvc0)
      nvc0->screen->cur_ctx = NULL;
   /* Unset bufctx, we don't want to revalidate any resources after the flush.
    * Other contexts will always set their bufctx again on action calls.
    */
   nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
   nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);

   nvc0_context_unreference_resources(nvc0);
   nvc0_blitctx_destroy(nvc0);

#ifdef NVC0_WITH_DRAW_MODULE
   draw_destroy(nvc0->draw);
#endif

   nouveau_context_destroy(&nvc0->base);
}
Exemple #15
0
void
nve4_p2mf_push_linear(struct nouveau_context *nv,
                      struct nouveau_bo *dst, unsigned offset, unsigned domain,
                      unsigned size, const void *data)
{
   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
   struct nouveau_pushbuf *push = nv->pushbuf;
   uint32_t *src = (uint32_t *)data;
   unsigned count = (size + 3) / 4;

   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
   nouveau_pushbuf_validate(push);

   while (count) {
      unsigned nr = MIN2(count, (NV04_PFIFO_MAX_PACKET_LEN - 1));

      if (!PUSH_SPACE(push, nr + 10))
         break;

      BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_DST_ADDRESS_HIGH), 2);
      PUSH_DATAh(push, dst->offset + offset);
      PUSH_DATA (push, dst->offset + offset);
      BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_LINE_LENGTH_IN), 2);
      PUSH_DATA (push, MIN2(size, nr * 4));
      PUSH_DATA (push, 1);
      /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
      BEGIN_1IC0(push, NVE4_P2MF(UPLOAD_EXEC), nr + 1);
      PUSH_DATA (push, 0x1001);
      PUSH_DATAp(push, src, nr);

      count -= nr;
      src += nr;
      offset += nr * 4;
      size -= nr * 4;
   }

   nouveau_bufctx_reset(nvc0->bufctx, 0);
}
Exemple #16
0
static void
nvc0_m2mf_copy_linear(struct nouveau_context *nv,
                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
                      unsigned size)
{
   struct nouveau_pushbuf *push = nv->pushbuf;
   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;

   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
   nouveau_pushbuf_bufctx(push, bctx);
   nouveau_pushbuf_validate(push);

   while (size) {
      unsigned bytes = MIN2(size, 1 << 17);

      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
      PUSH_DATAh(push, dst->offset + dstoff);
      PUSH_DATA (push, dst->offset + dstoff);
      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
      PUSH_DATAh(push, src->offset + srcoff);
      PUSH_DATA (push, src->offset + srcoff);
      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
      PUSH_DATA (push, bytes);
      PUSH_DATA (push, 1);
      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
      PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
                 NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT);

      srcoff += bytes;
      dstoff += bytes;
      size -= bytes;
   }

   nouveau_bufctx_reset(bctx, 0);
}
Exemple #17
0
static void
nvc0_resource_copy_region(struct pipe_context *pipe,
                          struct pipe_resource *dst, unsigned dst_level,
                          unsigned dstx, unsigned dsty, unsigned dstz,
                          struct pipe_resource *src, unsigned src_level,
                          const struct pipe_box *src_box)
{
   struct nvc0_context *nvc0 = nvc0_context(pipe);
   int ret;
   boolean m2mf;
   unsigned dst_layer = dstz, src_layer = src_box->z;

   if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
      nouveau_copy_buffer(&nvc0->base,
                          nv04_resource(dst), dstx,
                          nv04_resource(src), src_box->x, src_box->width);
      NOUVEAU_DRV_STAT(&nvc0->screen->base, buf_copy_bytes, src_box->width);
      return;
   }
   NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_copy_count, 1);

   /* 0 and 1 are equal, only supporting 0/1, 2, 4 and 8 */
   assert((src->nr_samples | 1) == (dst->nr_samples | 1));

   m2mf = (src->format == dst->format) ||
      (util_format_get_blocksizebits(src->format) ==
       util_format_get_blocksizebits(dst->format));

   nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;

   if (m2mf) {
      struct nv50_m2mf_rect drect, srect;
      unsigned i;
      unsigned nx = util_format_get_nblocksx(src->format, src_box->width);
      unsigned ny = util_format_get_nblocksy(src->format, src_box->height);

      nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz);
      nv50_m2mf_rect_setup(&srect, src, src_level,
                           src_box->x, src_box->y, src_box->z);

      for (i = 0; i < src_box->depth; ++i) {
         nvc0->m2mf_copy_rect(nvc0, &drect, &srect, nx, ny);

         if (nv50_miptree(dst)->layout_3d)
            drect.z++;
         else
            drect.base += nv50_miptree(dst)->layer_stride;

         if (nv50_miptree(src)->layout_3d)
            srect.z++;
         else
            srect.base += nv50_miptree(src)->layer_stride;
      }
      return;
   }

   assert(nv50_2d_dst_format_faithful(dst->format));
   assert(nv50_2d_src_format_faithful(src->format));

   BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
   BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
   nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
   nouveau_pushbuf_validate(nvc0->base.pushbuf);

   for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
      ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf,
                                    nv50_miptree(dst), dst_level,
                                    dstx, dsty, dst_layer,
                                    nv50_miptree(src), src_level,
                                    src_box->x, src_box->y, src_layer,
                                    src_box->width, src_box->height);
      if (ret)
         break;
   }
   nouveau_bufctx_reset(nvc0->bufctx, 0);
}
Exemple #18
0
Bool
NV30EXAPrepareComposite(int op, PicturePtr psPict,
		PicturePtr pmPict,
		PicturePtr pdPict,
		PixmapPtr  psPix,
		PixmapPtr  pmPix,
		PixmapPtr  pdPix)
{
	ScrnInfoPtr pScrn = xf86ScreenToScrn(pdPix->drawable.pScreen);
	NVPtr pNv = NVPTR(pScrn);
	nv_pict_op_t *blend = NV30_GetPictOpRec(op);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	uint32_t sc, sa, mc, ma, solid[2];

	if (!PUSH_SPACE(push, 128))
		return FALSE;
	PUSH_RESET(push);

	/* setup render target and blending */
	if (!NV30_SetupSurface(pScrn, pdPix, pdPict))
		return FALSE;
	NV30_SetupBlend(pScrn, blend, pdPict->format,
			(pmPict && pmPict->componentAlpha &&
			 PICT_FORMAT_RGB(pmPict->format)));

	/* select picture sources */
	if (!NV30EXAPicture(pScrn, psPix, psPict, 0, &sc, &sa, &solid[0]))
		return FALSE;
	if (!NV30EXAPicture(pScrn, pmPix, pmPict, 1, &mc, &ma, &solid[1]))
		return FALSE;

	/* configure register combiners */
	BEGIN_NV04(push, NV30_3D(RC_IN_ALPHA(0)), 6);
	PUSH_DATA (push, sa | ma);
	if (pmPict &&
	    pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) {
		if (blend->src_alpha)
			PUSH_DATA(push, sa | mc);
		else
			PUSH_DATA(push, sc | mc);
	} else {
		PUSH_DATA(push, sc | ma);
	}
	PUSH_DATA (push, solid[0]);
	PUSH_DATA (push, solid[1]);
	PUSH_DATA (push, 0x00000c00);
	PUSH_DATA (push, 0x00000c00);
	BEGIN_NV04(push, NV30_3D(RC_FINAL0), 3);
	if (pdPict->format != PICT_a8)
		PUSH_DATA (push, 0x0000000c);
	else
		PUSH_DATA (push, 0x0000001c);
	PUSH_DATA (push, 0x00001c00);
	PUSH_DATA (push, 0x01000101);

	/* select fragprog which just sources textures for combiners */
	BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
	PUSH_MTHD (push, NV30_3D(FP_ACTIVE_PROGRAM), pNv->scratch, PFP_PASS,
			 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
			 NOUVEAU_BO_OR,
			 NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
			 NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
	BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1);
	PUSH_DATA (push, 0x0001000f);
	BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
	PUSH_DATA (push, 0x00000000);
	BEGIN_NV04(push, NV30_3D(TEX_UNITS_ENABLE), 1);
	PUSH_DATA (push, 3);

	nouveau_pushbuf_bufctx(push, pNv->bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return FALSE;
	}

	return TRUE;
}
Exemple #19
0
struct pipe_context *
nvc0_create(struct pipe_screen *pscreen, void *priv)
{
   struct nvc0_screen *screen = nvc0_screen(pscreen);
   struct nvc0_context *nvc0;
   struct pipe_context *pipe;
   int ret;
   uint32_t flags;

   nvc0 = CALLOC_STRUCT(nvc0_context);
   if (!nvc0)
      return NULL;
   pipe = &nvc0->base.pipe;

   nvc0->base.pushbuf = screen->base.pushbuf;

   ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT,
                            &nvc0->bufctx_3d);
   if (!ret)
      nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
   if (ret)
      goto out_err;

   nvc0->screen = screen;
   nvc0->base.screen = &screen->base;

   pipe->screen = pscreen;
   pipe->priv = priv;

   pipe->destroy = nvc0_destroy;

   pipe->draw_vbo = nvc0_draw_vbo;
   pipe->clear = nvc0_clear;

   pipe->flush = nvc0_flush;
   pipe->texture_barrier = nvc0_texture_barrier;

   if (!screen->cur_ctx) {
      screen->cur_ctx = nvc0;
      nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
   }
   screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;

   nvc0_init_query_functions(nvc0);
   nvc0_init_surface_functions(nvc0);
   nvc0_init_state_functions(nvc0);
   nvc0_init_transfer_functions(nvc0);
   nvc0_init_resource_functions(pipe);

#ifdef NVC0_WITH_DRAW_MODULE
   /* no software fallbacks implemented */
   nvc0->draw = draw_create(pipe);
   assert(nvc0->draw);
   draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0));
#endif

   nouveau_context_init_vdec(&nvc0->base);

   /* shader builtin library is per-screen, but we need a context for m2mf */
   nvc0_program_library_upload(nvc0);

   /* add permanently resident buffers to bufctxts */

   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;

   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo);
   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);

   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
   BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);

   nvc0->base.scratch.bo_size = 2 << 20;

   return pipe;

out_err:
   if (nvc0) {
      if (nvc0->bufctx_3d)
         nouveau_bufctx_del(&nvc0->bufctx_3d);
      if (nvc0->bufctx)
         nouveau_bufctx_del(&nvc0->bufctx);
      FREE(nvc0);
   }
   return NULL;
}
Exemple #20
0
struct pipe_context *
nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
{
    struct nvc0_screen *screen = nvc0_screen(pscreen);
    struct nvc0_context *nvc0;
    struct pipe_context *pipe;
    int ret;
    uint32_t flags;

    nvc0 = CALLOC_STRUCT(nvc0_context);
    if (!nvc0)
        return NULL;
    pipe = &nvc0->base.pipe;

    if (!nvc0_blitctx_create(nvc0))
        goto out_err;

    nvc0->base.pushbuf = screen->base.pushbuf;
    nvc0->base.client = screen->base.client;

    ret = nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
    if (!ret)
        ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_3D_COUNT,
                                 &nvc0->bufctx_3d);
    if (!ret)
        ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_CP_COUNT,
                                 &nvc0->bufctx_cp);
    if (ret)
        goto out_err;

    nvc0->screen = screen;
    nvc0->base.screen = &screen->base;

    pipe->screen = pscreen;
    pipe->priv = priv;

    pipe->destroy = nvc0_destroy;

    pipe->draw_vbo = nvc0_draw_vbo;
    pipe->clear = nvc0_clear;
    pipe->launch_grid = (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) ?
                        nve4_launch_grid : nvc0_launch_grid;

    pipe->flush = nvc0_flush;
    pipe->texture_barrier = nvc0_texture_barrier;
    pipe->memory_barrier = nvc0_memory_barrier;
    pipe->get_sample_position = nvc0_context_get_sample_position;

    nouveau_context_init(&nvc0->base);
    nvc0_init_query_functions(nvc0);
    nvc0_init_surface_functions(nvc0);
    nvc0_init_state_functions(nvc0);
    nvc0_init_transfer_functions(nvc0);
    nvc0_init_resource_functions(pipe);

    nvc0->base.invalidate_resource_storage = nvc0_invalidate_resource_storage;

    pipe->create_video_codec = nvc0_create_decoder;
    pipe->create_video_buffer = nvc0_video_buffer_create;

    /* shader builtin library is per-screen, but we need a context for m2mf */
    nvc0_program_library_upload(nvc0);
    nvc0_program_init_tcp_empty(nvc0);
    if (!nvc0->tcp_empty)
        goto out_err;
    /* set the empty tctl prog on next draw in case one is never set */
    nvc0->dirty |= NVC0_NEW_TCTLPROG;

    /* now that there are no more opportunities for errors, set the current
     * context if there isn't already one.
     */
    if (!screen->cur_ctx) {
        nvc0->state = screen->save_state;
        screen->cur_ctx = nvc0;
        nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
    }
    screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;

    /* add permanently resident buffers to bufctxts */

    flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD;

    BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
    BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo);
    BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);
    if (screen->compute) {
        BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->text);
        BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->txc);
        BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->parm);
    }

    flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR;

    if (screen->poly_cache)
        BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->poly_cache);
    if (screen->compute)
        BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->tls);

    flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

    BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
    BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);
    if (screen->compute)
        BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->fence.bo);

    nvc0->base.scratch.bo_size = 2 << 20;

    memset(nvc0->tex_handles, ~0, sizeof(nvc0->tex_handles));

    util_dynarray_init(&nvc0->global_residents);

    return pipe;

out_err:
    if (nvc0) {
        if (nvc0->bufctx_3d)
            nouveau_bufctx_del(&nvc0->bufctx_3d);
        if (nvc0->bufctx_cp)
            nouveau_bufctx_del(&nvc0->bufctx_cp);
        if (nvc0->bufctx)
            nouveau_bufctx_del(&nvc0->bufctx);
        FREE(nvc0->blit);
        FREE(nvc0);
    }
    return NULL;
}
Exemple #21
0
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv)
{
   struct nv50_screen *screen = nv50_screen(pscreen);
   struct nv50_context *nv50;
   struct pipe_context *pipe;
   int ret;
   uint32_t flags;

   nv50 = CALLOC_STRUCT(nv50_context);
   if (!nv50)
      return NULL;
   pipe = &nv50->base.pipe;

   if (!nv50_blitctx_create(nv50))
      goto out_err;

   nv50->base.pushbuf = screen->base.pushbuf;
   nv50->base.client = screen->base.client;

   ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT,
                            &nv50->bufctx_3d);
   if (!ret)
      ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
   if (ret)
      goto out_err;

   nv50->base.screen    = &screen->base;
   nv50->base.copy_data = nv50_m2mf_copy_linear;
   nv50->base.push_data = nv50_sifc_linear_u8;
   nv50->base.push_cb   = nv50_cb_push;

   nv50->screen = screen;
   pipe->screen = pscreen;
   pipe->priv = priv;

   pipe->destroy = nv50_destroy;

   pipe->draw_vbo = nv50_draw_vbo;
   pipe->clear = nv50_clear;

   pipe->flush = nv50_flush;
   pipe->texture_barrier = nv50_texture_barrier;

   if (!screen->cur_ctx) {
      screen->cur_ctx = nv50;
      nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
   }

   nv50_init_query_functions(nv50);
   nv50_init_surface_functions(nv50);
   nv50_init_state_functions(nv50);
   nv50_init_resource_functions(pipe);

   nv50->base.invalidate_resource_storage = nv50_invalidate_resource_storage;

#ifdef NV50_WITH_DRAW_MODULE
   /* no software fallbacks implemented */
   nv50->draw = draw_create(pipe);
   assert(nv50->draw);
   draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
#endif

   nouveau_context_init_vdec(&nv50->base);

   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;

   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->code);
   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms);
   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc);
   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo);

   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo);
   BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);

   nv50->base.scratch.bo_size = 2 << 20;

   return pipe;

out_err:
   if (nv50) {
      if (nv50->bufctx_3d)
         nouveau_bufctx_del(&nv50->bufctx_3d);
      if (nv50->bufctx)
         nouveau_bufctx_del(&nv50->bufctx);
      if (nv50->blit)
         FREE(nv50->blit);
      FREE(nv50);
   }
   return NULL;
}
Exemple #22
0
void
NV40EXADoneComposite(PixmapPtr pdPix)
{
	ScrnInfoPtr pScrn = xf86ScreenToScrn(pdPix->drawable.pScreen);
	nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL);
}
Exemple #23
0
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
{
   struct nv50_screen *screen = nv50_screen(pscreen);
   struct nv50_context *nv50;
   struct pipe_context *pipe;
   int ret;
   uint32_t flags;

   nv50 = CALLOC_STRUCT(nv50_context);
   if (!nv50)
      return NULL;
   pipe = &nv50->base.pipe;

   if (!nv50_blitctx_create(nv50))
      goto out_err;

   nv50->base.pushbuf = screen->base.pushbuf;
   nv50->base.client = screen->base.client;

   ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
   if (!ret)
      ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_3D_COUNT,
                               &nv50->bufctx_3d);
   if (!ret)
      ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_CP_COUNT,
                               &nv50->bufctx_cp);
   if (ret)
      goto out_err;

   nv50->base.screen    = &screen->base;
   nv50->base.copy_data = nv50_m2mf_copy_linear;
   nv50->base.push_data = nv50_sifc_linear_u8;
   /* FIXME: Make it possible to use this again. The problem is that there is
    * some clever logic in the card that allows for multiple renders to happen
    * when there are only constbuf changes. However that relies on the
    * constbuf updates happening to the right constbuf slots. Currently
    * implementation just makes it go through a separate slot which doesn't
    * properly update the right constbuf data.
   nv50->base.push_cb   = nv50_cb_push;
    */

   nv50->screen = screen;
   pipe->screen = pscreen;
   pipe->priv = priv;

   pipe->destroy = nv50_destroy;

   pipe->draw_vbo = nv50_draw_vbo;
   pipe->clear = nv50_clear;
   pipe->launch_grid = nv50_launch_grid;

   pipe->flush = nv50_flush;
   pipe->texture_barrier = nv50_texture_barrier;
   pipe->memory_barrier = nv50_memory_barrier;
   pipe->get_sample_position = nv50_context_get_sample_position;

   if (!screen->cur_ctx) {
      /* Restore the last context's state here, normally handled during
       * context switch
       */
      nv50->state = screen->save_state;
      screen->cur_ctx = nv50;
      nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
   }
   nv50->base.pushbuf->kick_notify = nv50_default_kick_notify;

   nouveau_context_init(&nv50->base);
   nv50_init_query_functions(nv50);
   nv50_init_surface_functions(nv50);
   nv50_init_state_functions(nv50);
   nv50_init_resource_functions(pipe);

   nv50->base.invalidate_resource_storage = nv50_invalidate_resource_storage;

   if (screen->base.device->chipset < 0x84 ||
       debug_get_bool_option("NOUVEAU_PMPEG", false)) {
      /* PMPEG */
      nouveau_context_init_vdec(&nv50->base);
   } else if (screen->base.device->chipset < 0x98 ||
              screen->base.device->chipset == 0xa0) {
      /* VP2 */
      pipe->create_video_codec = nv84_create_decoder;
      pipe->create_video_buffer = nv84_video_buffer_create;
   } else {
      /* VP3/4 */
      pipe->create_video_codec = nv98_create_decoder;
      pipe->create_video_buffer = nv98_video_buffer_create;
   }

   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;

   BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->code);
   BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->uniforms);
   BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->txc);
   BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->stack_bo);
   if (screen->compute) {
      BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->code);
      BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->txc);
      BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->stack_bo);
   }

   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

   BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->fence.bo);
   BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);
   if (screen->compute)
      BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->fence.bo);

   nv50->base.scratch.bo_size = 2 << 20;

   util_dynarray_init(&nv50->global_residents);

   return pipe;

out_err:
   if (nv50->bufctx_3d)
      nouveau_bufctx_del(&nv50->bufctx_3d);
   if (nv50->bufctx_cp)
      nouveau_bufctx_del(&nv50->bufctx_cp);
   if (nv50->bufctx)
      nouveau_bufctx_del(&nv50->bufctx);
   FREE(nv50->blit);
   FREE(nv50);
   return NULL;
}
Exemple #24
0
Bool
NV40EXAPrepareComposite(int op, PicturePtr psPict,
				PicturePtr pmPict,
				PicturePtr pdPict,
				PixmapPtr  psPix,
				PixmapPtr  pmPix,
				PixmapPtr  pdPix)
{
	ScrnInfoPtr pScrn = xf86ScreenToScrn(pdPix->drawable.pScreen);
	NVPtr pNv = NVPTR(pScrn);
	nv_pict_op_t *blend = NV40_GetPictOpRec(op);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	uint32_t fragprog;

	if (!PUSH_SPACE(push, 128))
		NOUVEAU_FALLBACK("space\n");
	PUSH_RESET(push);

	NV40_SetupBlend(pScrn, blend, pdPict->format,
			(pmPict && pmPict->componentAlpha &&
			 PICT_FORMAT_RGB(pmPict->format)));

	if (!NV40_SetupSurface(pScrn, pdPix, pdPict->format) ||
	    !NV40EXAPicture(pNv, psPix, psPict, 0))
		return FALSE;

	if (pmPict) {
		if (!NV40EXAPicture(pNv, pmPix, pmPict, 1))
			return FALSE;

		if (pdPict->format == PICT_a8) {
			fragprog = PFP_C_A8;
		} else
		if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) {
			if (blend->src_alpha)
				fragprog = PFP_CCASA;
			else
				fragprog = PFP_CCA;
		} else {
			fragprog = PFP_C;
		}
	} else {
		if (pdPict->format == PICT_a8)
			fragprog = PFP_S_A8;
		else
			fragprog = PFP_S;
	}

	BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
	PUSH_MTHD (push, NV30_3D(FP_ACTIVE_PROGRAM), pNv->scratch, fragprog,
			 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
			 NOUVEAU_BO_OR,
			 NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
			 NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
	BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
	PUSH_DATA (push, 0x02000000);

	/* Appears to be some kind of cache flush, needed here at least
	 * sometimes.. funky text rendering otherwise :)
	 */
	BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
	PUSH_DATA (push, 2);
	BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
	PUSH_DATA (push, 1);

	nouveau_pushbuf_bufctx(push, pNv->bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return FALSE;
	}

	return TRUE;
}
Exemple #25
0
static void
nve4_m2mf_transfer_rect(struct nvc0_context *nvc0,
                        const struct nv50_m2mf_rect *dst,
                        const struct nv50_m2mf_rect *src,
                        uint32_t nblocksx, uint32_t nblocksy)
{
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   struct nouveau_bufctx *bctx = nvc0->bufctx;
   uint32_t exec;
   uint32_t src_base = src->base;
   uint32_t dst_base = dst->base;
   const int cpp = dst->cpp;

   assert(dst->cpp == src->cpp);

   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
   nouveau_pushbuf_bufctx(push, bctx);
   nouveau_pushbuf_validate(push);

   exec = 0x200 /* 2D_ENABLE */ | 0x6 /* UNK */;

   if (!nouveau_bo_memtype(dst->bo)) {
      assert(!dst->z);
      dst_base += dst->y * dst->pitch + dst->x * cpp;
      exec |= 0x100; /* DST_MODE_2D_LINEAR */
   }
   if (!nouveau_bo_memtype(src->bo)) {
      assert(!src->z);
      src_base += src->y * src->pitch + src->x * cpp;
      exec |= 0x080; /* SRC_MODE_2D_LINEAR */
   }

   BEGIN_NVC0(push, SUBC_COPY(0x070c), 6);
   PUSH_DATA (push, 0x1000 | dst->tile_mode);
   PUSH_DATA (push, dst->pitch);
   PUSH_DATA (push, dst->height);
   PUSH_DATA (push, dst->depth);
   PUSH_DATA (push, dst->z);
   PUSH_DATA (push, (dst->y << 16) | (dst->x * cpp));

   BEGIN_NVC0(push, SUBC_COPY(0x0728), 6);
   PUSH_DATA (push, 0x1000 | src->tile_mode);
   PUSH_DATA (push, src->pitch);
   PUSH_DATA (push, src->height);
   PUSH_DATA (push, src->depth);
   PUSH_DATA (push, src->z);
   PUSH_DATA (push, (src->y << 16) | (src->x * cpp));

   BEGIN_NVC0(push, SUBC_COPY(0x0400), 8);
   PUSH_DATAh(push, src->bo->offset + src_base);
   PUSH_DATA (push, src->bo->offset + src_base);
   PUSH_DATAh(push, dst->bo->offset + dst_base);
   PUSH_DATA (push, dst->bo->offset + dst_base);
   PUSH_DATA (push, src->pitch);
   PUSH_DATA (push, dst->pitch);
   PUSH_DATA (push, nblocksx * cpp);
   PUSH_DATA (push, nblocksy);

   BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
   PUSH_DATA (push, exec);

   nouveau_bufctx_reset(bctx, 0);
}
Exemple #26
0
static void
nvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
                        const struct nv50_m2mf_rect *dst,
                        const struct nv50_m2mf_rect *src,
                        uint32_t nblocksx, uint32_t nblocksy)
{
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   struct nouveau_bufctx *bctx = nvc0->bufctx;
   const int cpp = dst->cpp;
   uint32_t src_ofst = src->base;
   uint32_t dst_ofst = dst->base;
   uint32_t height = nblocksy;
   uint32_t sy = src->y;
   uint32_t dy = dst->y;
   uint32_t exec = (1 << 20);

   assert(dst->cpp == src->cpp);

   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
   nouveau_pushbuf_bufctx(push, bctx);
   nouveau_pushbuf_validate(push);

   if (nouveau_bo_memtype(src->bo)) {
      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
      PUSH_DATA (push, src->tile_mode);
      PUSH_DATA (push, src->width * cpp);
      PUSH_DATA (push, src->height);
      PUSH_DATA (push, src->depth);
      PUSH_DATA (push, src->z);
   } else {
      src_ofst += src->y * src->pitch + src->x * cpp;

      BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1);
      PUSH_DATA (push, src->width * cpp);

      exec |= NVC0_M2MF_EXEC_LINEAR_IN;
   }

   if (nouveau_bo_memtype(dst->bo)) {
      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5);
      PUSH_DATA (push, dst->tile_mode);
      PUSH_DATA (push, dst->width * cpp);
      PUSH_DATA (push, dst->height);
      PUSH_DATA (push, dst->depth);
      PUSH_DATA (push, dst->z);
   } else {
      dst_ofst += dst->y * dst->pitch + dst->x * cpp;

      BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1);
      PUSH_DATA (push, dst->width * cpp);

      exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
   }

   while (height) {
      int line_count = height > 2047 ? 2047 : height;

      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
      PUSH_DATAh(push, src->bo->offset + src_ofst);
      PUSH_DATA (push, src->bo->offset + src_ofst);

      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
      PUSH_DATAh(push, dst->bo->offset + dst_ofst);
      PUSH_DATA (push, dst->bo->offset + dst_ofst);

      if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) {
         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2);
         PUSH_DATA (push, src->x * cpp);
         PUSH_DATA (push, sy);
      } else {
         src_ofst += line_count * src->pitch;
      }
      if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) {
         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2);
         PUSH_DATA (push, dst->x * cpp);
         PUSH_DATA (push, dy);
      } else {
         dst_ofst += line_count * dst->pitch;
      }

      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
      PUSH_DATA (push, nblocksx * cpp);
      PUSH_DATA (push, line_count);
      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
      PUSH_DATA (push, exec);

      height -= line_count;
      sy += line_count;
      dy += line_count;
   }

   nouveau_bufctx_reset(bctx, 0);
}
Exemple #27
0
struct pipe_context *
nvc0_create(struct pipe_screen *pscreen, void *priv)
{
   struct nvc0_screen *screen = nvc0_screen(pscreen);
   struct nvc0_context *nvc0;
   struct pipe_context *pipe;
   int ret;
   uint32_t flags;

   nvc0 = CALLOC_STRUCT(nvc0_context);
   if (!nvc0)
      return NULL;
   pipe = &nvc0->base.pipe;

   if (!nvc0_blitctx_create(nvc0))
      goto out_err;

   nvc0->base.pushbuf = screen->base.pushbuf;
   nvc0->base.client = screen->base.client;

   ret = nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
   if (!ret)
      ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_3D_COUNT,
                               &nvc0->bufctx_3d);
   if (!ret)
      ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_CP_COUNT,
                               &nvc0->bufctx_cp);
   if (ret)
      goto out_err;

   nvc0->screen = screen;
   nvc0->base.screen = &screen->base;

   pipe->screen = pscreen;
   pipe->priv = priv;

   pipe->destroy = nvc0_destroy;

   pipe->draw_vbo = nvc0_draw_vbo;
   pipe->clear = nvc0_clear;
   pipe->launch_grid = (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) ?
      nve4_launch_grid : nvc0_launch_grid;

   pipe->flush = nvc0_flush;
   pipe->texture_barrier = nvc0_texture_barrier;
   pipe->memory_barrier = nvc0_memory_barrier;
   pipe->get_sample_position = nvc0_context_get_sample_position;

   if (!screen->cur_ctx) {
      screen->cur_ctx = nvc0;
      nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
   }
   screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;

   nvc0_init_query_functions(nvc0);
   nvc0_init_surface_functions(nvc0);
   nvc0_init_state_functions(nvc0);
   nvc0_init_transfer_functions(nvc0);
   nvc0_init_resource_functions(pipe);

   nvc0->base.invalidate_resource_storage = nvc0_invalidate_resource_storage;

#ifdef NVC0_WITH_DRAW_MODULE
   /* no software fallbacks implemented */
   nvc0->draw = draw_create(pipe);
   assert(nvc0->draw);
   draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0));
#endif

   pipe->create_video_codec = nvc0_create_decoder;
   pipe->create_video_buffer = nvc0_video_buffer_create;

   /* shader builtin library is per-screen, but we need a context for m2mf */
   nvc0_program_library_upload(nvc0);

   /* add permanently resident buffers to bufctxts */

   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;

   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo);
   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);
   if (screen->compute) {
      BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->text);
      BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->txc);
      BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->parm);
   }

   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;

   if (screen->poly_cache)
      BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->poly_cache);
   if (screen->compute)
      BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->tls);

   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
   BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);
   if (screen->compute)
      BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->fence.bo);

   nvc0->base.scratch.bo_size = 2 << 20;

   memset(nvc0->tex_handles, ~0, sizeof(nvc0->tex_handles));

   util_dynarray_init(&nvc0->global_residents);

   return pipe;

out_err:
   if (nvc0) {
      if (nvc0->bufctx_3d)
         nouveau_bufctx_del(&nvc0->bufctx_3d);
      if (nvc0->bufctx_cp)
         nouveau_bufctx_del(&nvc0->bufctx_cp);
      if (nvc0->bufctx)
         nouveau_bufctx_del(&nvc0->bufctx);
      if (nvc0->blit)
         FREE(nvc0->blit);
      FREE(nvc0);
   }
   return NULL;
}
Exemple #28
0
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
{
    struct nv50_screen *screen = nv50_screen(pscreen);
    struct nv50_context *nv50;
    struct pipe_context *pipe;
    int ret;
    uint32_t flags;

    nv50 = CALLOC_STRUCT(nv50_context);
    if (!nv50)
        return NULL;
    pipe = &nv50->base.pipe;

    if (!nv50_blitctx_create(nv50))
        goto out_err;

    nv50->base.pushbuf = screen->base.pushbuf;
    nv50->base.client = screen->base.client;

    ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
    if (!ret)
        ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_3D_COUNT,
                                 &nv50->bufctx_3d);
    if (!ret)
        ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_CP_COUNT,
                                 &nv50->bufctx_cp);
    if (ret)
        goto out_err;

    nv50->base.screen    = &screen->base;
    nv50->base.copy_data = nv50_m2mf_copy_linear;
    nv50->base.push_data = nv50_sifc_linear_u8;
    nv50->base.push_cb   = nv50_cb_push;

    nv50->screen = screen;
    pipe->screen = pscreen;
    pipe->priv = priv;

    pipe->destroy = nv50_destroy;

    pipe->draw_vbo = nv50_draw_vbo;
    pipe->clear = nv50_clear;
    pipe->launch_grid = nv50_launch_grid;

    pipe->flush = nv50_flush;
    pipe->texture_barrier = nv50_texture_barrier;
    pipe->memory_barrier = nv50_memory_barrier;
    pipe->get_sample_position = nv50_context_get_sample_position;
    pipe->emit_string_marker = nv50_emit_string_marker;

    if (!screen->cur_ctx) {
        /* Restore the last context's state here, normally handled during
         * context switch
         */
        nv50->state = screen->save_state;
        screen->cur_ctx = nv50;
        nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
    }
    nv50->base.pushbuf->kick_notify = nv50_default_kick_notify;

    nouveau_context_init(&nv50->base);
    nv50_init_query_functions(nv50);
    nv50_init_surface_functions(nv50);
    nv50_init_state_functions(nv50);
    nv50_init_resource_functions(pipe);

    nv50->base.invalidate_resource_storage = nv50_invalidate_resource_storage;

    if (screen->base.device->chipset < 0x84 ||
            debug_get_bool_option("NOUVEAU_PMPEG", false)) {
        /* PMPEG */
        nouveau_context_init_vdec(&nv50->base);
    } else if (screen->base.device->chipset < 0x98 ||
               screen->base.device->chipset == 0xa0) {
        /* VP2 */
        pipe->create_video_codec = nv84_create_decoder;
        pipe->create_video_buffer = nv84_video_buffer_create;
    } else {
        /* VP3/4 */
        pipe->create_video_codec = nv98_create_decoder;
        pipe->create_video_buffer = nv98_video_buffer_create;
    }

    flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;

    BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->code);
    BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->uniforms);
    BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->txc);
    BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->stack_bo);
    if (screen->compute) {
        BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->code);
        BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->txc);
        BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->stack_bo);
    }

    flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

    BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->fence.bo);
    BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);
    if (screen->compute)
        BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->fence.bo);

    nv50->base.scratch.bo_size = 2 << 20;

    util_dynarray_init(&nv50->global_residents);

    return pipe;

out_err:
    if (nv50->bufctx_3d)
        nouveau_bufctx_del(&nv50->bufctx_3d);
    if (nv50->bufctx_cp)
        nouveau_bufctx_del(&nv50->bufctx_cp);
    if (nv50->bufctx)
        nouveau_bufctx_del(&nv50->bufctx);
    FREE(nv50->blit);
    FREE(nv50);
    return NULL;
}