예제 #1
0
파일: nv30_push.c 프로젝트: DirectFB/mesa
static void
emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
{
   uint8_t *elts = (uint8_t *)ctx->idxbuf + start;

   while (count) {
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
      unsigned size, nr;

      nr = push;
      if (ctx->primitive_restart)
         nr = prim_restart_search_i08(elts, push, ctx->restart_index);

      size = ctx->vertex_words * nr;

      BEGIN_NI04(ctx->push, NV30_3D(VERTEX_DATA), size);

      ctx->translate->run_elts8(ctx->translate, elts, nr, 0, 0, ctx->push->cur);

      ctx->push->cur += size;
      count -= nr;
      elts += nr;

      if (nr != push) {
         BEGIN_NV04(ctx->push, NV30_3D(VB_ELEMENT_U32), 1);
         PUSH_DATA (ctx->push, ctx->restart_index);
         count--;
         elts++;
      }
   }
}
static void
nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_query *q = nv30_query(pq);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;

   switch (q->type) {
   case PIPE_QUERY_TIME_ELAPSED:
      q->qo[0] = nv30_query_object_new(nv30->screen);
      if (q->qo[0]) {
         BEGIN_NV04(push, NV30_3D(QUERY_GET), 1);
         PUSH_DATA (push, (q->report << 24) | q->qo[0]->hw->start);
      }
      break;
   case PIPE_QUERY_TIMESTAMP:
      return;
   default:
      BEGIN_NV04(push, NV30_3D(QUERY_RESET), 1);
      PUSH_DATA (push, q->report);
      break;
   }

   if (q->enable) {
      BEGIN_NV04(push, SUBC_3D(q->enable), 1);
      PUSH_DATA (push, 1);
   }
}
예제 #3
0
void
NV40EXAComposite(PixmapPtr pdPix,
		 int sx, int sy, int mx, int my, int dx, int dy, int w, int h)
{
	ScrnInfoPtr pScrn = xf86ScreenToScrn(pdPix->drawable.pScreen);
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_pushbuf *push = pNv->pushbuf;

	if (!PUSH_SPACE(push, 64))
		return;

	/* We're drawing a triangle, we need to scissor it to a quad. */
	/* The scissors are here for a good reason, we don't get the full
	 * image, but just a part.
	 */
	/* Handling the cliprects is done for us already. */
	BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
	PUSH_DATA (push, (w << 16) | dx);
	PUSH_DATA (push, (h << 16) | dy);
	BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
	PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_TRIANGLES);
	PUSH_VTX2s(push, sx, sy + (h * 2), mx, my + (h * 2), dx, dy + (h * 2));
	PUSH_VTX2s(push, sx, sy, mx, my, dx, dy);
	PUSH_VTX2s(push, sx + (w * 2), sy, mx + (w * 2), my, dx + (w * 2), dy);
	BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
	PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
}
static void
nv30_draw_arrays(struct nv30_context *nv30,
                 unsigned mode, unsigned start, unsigned count,
                 unsigned instance_count)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   unsigned prim;

   prim = nv30_prim_gl(mode);

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, prim);
   while (count) {
      const unsigned mpush = 2047 * 256;
      unsigned npush  = (count > mpush) ? mpush : count;
      unsigned wpush  = ((npush + 255) & ~255) >> 8;

      count -= npush;

      BEGIN_NI04(push, NV30_3D(VB_VERTEX_BATCH), wpush);
      while (npush >= 256) {
         PUSH_DATA (push, 0xff000000 | start);
         start += 256;
         npush -= 256;
      }

      if (npush)
         PUSH_DATA (push, ((npush - 1) << 24) | start);
   }
   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
}
예제 #5
0
파일: nv30_clear.c 프로젝트: DirectFB/mesa
static void
nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
                         const union pipe_color_union *color,
                         unsigned x, unsigned y, unsigned w, unsigned h)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_surface *sf = nv30_surface(ps);
   struct nv30_miptree *mt = nv30_miptree(ps->texture);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nouveau_pushbuf_refn refn;
   uint32_t rt_format;

   rt_format = nv30_format(pipe->screen, ps->format)->hw;
   if (util_format_get_blocksize(ps->format) == 4)
      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
   else
      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;

   if (nv30_miptree(ps->texture)->swizzled) {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      rt_format |= util_logbase2(sf->width) << 16;
      rt_format |= util_logbase2(sf->height) << 24;
   } else {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
   }

   refn.bo = mt->base.bo;
   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
   if (nouveau_pushbuf_space(push, 16, 1, 0) ||
       nouveau_pushbuf_refn (push, &refn, 1))
      return;

   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
   PUSH_DATA (push, sf->width << 16);
   PUSH_DATA (push, sf->height << 16);
   PUSH_DATA (push, rt_format);
   BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);
   if (eng3d->oclass < NV40_3D_CLASS)
      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
   else
      PUSH_DATA (push, sf->pitch);
   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (w << 16) | x);
   PUSH_DATA (push, (h << 16) | y);

   BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);
   PUSH_DATA (push, pack_rgba(ps->format, color->f));
   PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |
                    NV30_3D_CLEAR_BUFFERS_COLOR_G |
                    NV30_3D_CLEAR_BUFFERS_COLOR_B |
                    NV30_3D_CLEAR_BUFFERS_COLOR_A);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
예제 #6
0
static __inline__ void
PUSH_VTX2s(struct nouveau_pushbuf *push,
	   int x1, int y1, int x2, int y2, int dx, int dy)
{
	BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(8)), 2);
	PUSH_DATA (push, (y1 << 16) | x1);
	PUSH_DATA (push, (y2 << 16) | x2);
	BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
	PUSH_DATA (push, (dy << 16) | dx);
}
예제 #7
0
static __inline__ void
PUSH_VTX2s(struct nouveau_pushbuf *push,
	   int x1, int y1, int x2, int y2, int dx, int dy)
{
	BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(8)), 2);
	PUSH_DATA (push, ((y1 & 0xffff) << 16) | (x1 & 0xffff));
	PUSH_DATA (push, ((y2 & 0xffff) << 16) | (x2 & 0xffff));
	BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
	PUSH_DATA (push, ((dy & 0xffff) << 16) | (dx & 0xffff));
}
예제 #8
0
static Bool
NV40EXAPictSolid(NVPtr pNv, PicturePtr pPict, int unit)
{
	struct nouveau_pushbuf *push = pNv->pushbuf;

	PUSH_DATAu(push, pNv->scratch, SOLID(unit), 2);
	PUSH_DATA (push, pPict->pSourcePict->solidFill.color);
	PUSH_DATA (push, 0);
	BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8);
	PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), pNv->scratch, SOLID(unit),
			 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
	PUSH_DATA (push, NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8 | 0x8000 |
			 NV40_3D_TEX_FORMAT_LINEAR |
			 NV30_3D_TEX_FORMAT_DIMS_2D |
			 NV30_3D_TEX_FORMAT_NO_BORDER |
			 (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT) |
			 NV30_3D_TEX_FORMAT_DMA0);
	PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT |
			 NV30_3D_TEX_WRAP_T_REPEAT |
			 NV30_3D_TEX_WRAP_R_REPEAT);
	PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE);
	PUSH_DATA (push, 0x0000aae4);
	PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST |
			 NV30_3D_TEX_FILTER_MAG_NEAREST | 0x3fd6);
	PUSH_DATA (push, 0x00010001);
	PUSH_DATA (push, 0x00000000);
	BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1);
	PUSH_DATA (push, 0x00100040);

	BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 17);
	PUSH_DATA (push, unit * 4);
	PUSH_DATAf(push, 1.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 1.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 1.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 1.0);
	PUSH_DATAf(push, 1.0);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 0.0);
	return TRUE;
}
예제 #9
0
static void
NV40_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend,
		PictFormatShort dest_format, Bool component_alpha)
{
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	uint32_t sblend, dblend;

	sblend = blend->src_card_op;
	dblend = blend->dst_card_op;

	if (blend->dst_alpha) {
		if (!PICT_FORMAT_A(dest_format)) {
			if (sblend == SF(DST_ALPHA)) {
				sblend = SF(ONE);
			} else if (sblend == SF(ONE_MINUS_DST_ALPHA)) {
				sblend = SF(ZERO);
			}
		} else if (dest_format == PICT_a8) {
			if (sblend == SF(DST_ALPHA)) {
				sblend = SF(DST_COLOR);
			} else if (sblend == SF(ONE_MINUS_DST_ALPHA)) {
				sblend = SF(ONE_MINUS_DST_COLOR);
			}
		}
	}

	if (blend->src_alpha && (component_alpha || dest_format == PICT_a8)) {
		if (dblend == DF(SRC_ALPHA)) {
			dblend = DF(SRC_COLOR);
		} else if (dblend == DF(ONE_MINUS_SRC_ALPHA)) {
			dblend = DF(ONE_MINUS_SRC_COLOR);
		}
	}

	if (sblend == SF(ONE) && dblend == DF(ZERO)) {
		BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1);
		PUSH_DATA (push, 0);
	} else {
		BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 5);
		PUSH_DATA (push, 1);
		PUSH_DATA (push, sblend);
		PUSH_DATA (push, dblend);
		PUSH_DATA (push, 0x00000000);
		PUSH_DATA (push, NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD |
				 NV40_3D_BLEND_EQUATION_RGB_FUNC_ADD);
	}
}
예제 #10
0
static void
nv30_emit_vtxattr(struct nv30_context *nv30, struct pipe_vertex_buffer *vb,
                  struct pipe_vertex_element *ve, unsigned attr)
{
   const unsigned nc = util_format_get_nr_components(ve->src_format);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nv04_resource *res = nv04_resource(vb->buffer);
   const struct util_format_description *desc =
      util_format_description(ve->src_format);
   const void *data;
   float v[4];

   data = nouveau_resource_map_offset(&nv30->base, res, vb->buffer_offset +
                                      ve->src_offset, NOUVEAU_BO_RD);

   desc->unpack_rgba_float(v, 0, data, 0, 1, 1);

   switch (nc) {
   case 4:
      BEGIN_NV04(push, NV30_3D(VTX_ATTR_4F(attr)), 4);
      PUSH_DATAf(push, v[0]);
      PUSH_DATAf(push, v[1]);
      PUSH_DATAf(push, v[2]);
      PUSH_DATAf(push, v[3]);
      break;
   case 3:
      BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(attr)), 3);
      PUSH_DATAf(push, v[0]);
      PUSH_DATAf(push, v[1]);
      PUSH_DATAf(push, v[2]);
      break;
   case 2:
      BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F(attr)), 2);
      PUSH_DATAf(push, v[0]);
      PUSH_DATAf(push, v[1]);
      break;
   case 1:
      BEGIN_NV04(push, NV30_3D(VTX_ATTR_1F(attr)), 1);
      PUSH_DATAf(push, v[0]);
      break;
   default:
      assert(0);
      break;
   }
}
예제 #11
0
파일: nv30_clear.c 프로젝트: DirectFB/mesa
static void
nv30_clear(struct pipe_context *pipe, unsigned buffers,
           const union pipe_color_union *color, double depth, unsigned stencil)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct pipe_framebuffer_state *fb = &nv30->framebuffer;
   uint32_t colr = 0, zeta = 0, mode = 0;

   if (!nv30_state_validate(nv30, TRUE))
      return;

   if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
      colr  = pack_rgba(fb->cbufs[0]->format, color->f);
      mode |= NV30_3D_CLEAR_BUFFERS_COLOR_R |
              NV30_3D_CLEAR_BUFFERS_COLOR_G |
              NV30_3D_CLEAR_BUFFERS_COLOR_B |
              NV30_3D_CLEAR_BUFFERS_COLOR_A;
   }

   if (fb->zsbuf) {
      zeta = pack_zeta(fb->zsbuf->format, depth, stencil);
      if (buffers & PIPE_CLEAR_DEPTH)
         mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
      if (buffers & PIPE_CLEAR_STENCIL)
         mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
   }

   /*XXX: wtf? fixes clears sometimes not clearing on nv3x... */
   if (nv30->screen->eng3d->oclass < NV40_3D_CLASS) {
      BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
      PUSH_DATA (push, zeta);
      PUSH_DATA (push, colr);
      PUSH_DATA (push, mode);
   }

   BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
   PUSH_DATA (push, zeta);
   PUSH_DATA (push, colr);
   PUSH_DATA (push, mode);

   nv30_state_release(nv30);
}
예제 #12
0
static void
nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
{
   struct nv30_screen *screen = nv30_screen(pscreen);
   struct nouveau_pushbuf *push = screen->base.pushbuf;

   *sequence = ++screen->base.fence.sequence;

   BEGIN_NV04(push, NV30_3D(FENCE_OFFSET), 2);
   PUSH_DATA (push, 0);
   PUSH_DATA (push, *sequence);
}
static void
nv30_draw_elements(struct nv30_context *nv30, boolean shorten,
                   unsigned mode, unsigned start, unsigned count,
                   unsigned instance_count, int32_t index_bias)
{
   const unsigned index_size = nv30->idxbuf.index_size;
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   unsigned prim = nv30_prim_gl(mode);

#if 0 /*XXX*/
   if (index_bias != nv30->state.index_bias) {
      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_BASE), 1);
      PUSH_DATA (push, index_bias);
      nv30->state.index_bias = index_bias;
   }
#endif

   if (eng3d->oclass == NV40_3D_CLASS && index_size > 1 &&
       nv30->idxbuf.buffer) {
      struct nv04_resource *res = nv04_resource(nv30->idxbuf.buffer);
      unsigned offset = nv30->idxbuf.offset;

      assert(nouveau_resource_mapped_by_gpu(&res->base));

      BEGIN_NV04(push, NV30_3D(IDXBUF_OFFSET), 2);
      PUSH_RESRC(push, NV30_3D(IDXBUF_OFFSET), BUFCTX_IDXBUF, res, offset,
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
      PUSH_MTHD (push, NV30_3D(IDXBUF_FORMAT), BUFCTX_IDXBUF, res->bo,
                       (index_size == 2) ? 0x00000010 : 0x00000000,
                       res->domain | NOUVEAU_BO_RD,
                       0, NV30_3D_IDXBUF_FORMAT_DMA1);
      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
      PUSH_DATA (push, prim);
      while (count) {
         const unsigned mpush = 2047 * 256;
         unsigned npush  = (count > mpush) ? mpush : count;
         unsigned wpush  = ((npush + 255) & ~255) >> 8;

         count -= npush;

         BEGIN_NI04(push, NV30_3D(VB_INDEX_BATCH), wpush);
         while (npush >= 256) {
            PUSH_DATA (push, 0xff000000 | start);
            start += 256;
            npush -= 256;
         }

         if (npush)
            PUSH_DATA (push, ((npush - 1) << 24) | start);
      }
      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
      PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
      PUSH_RESET(push, BUFCTX_IDXBUF);
   } else {
예제 #14
0
static inline struct nouveau_heap *
nv30_transfer_rect_vertprog(struct nv30_context *nv30)
{
   struct nouveau_heap *heap = nv30->screen->vp_exec_heap;
   struct nouveau_heap *vp;

   vp = nv30->blit_vp;
   if (!vp) {
      if (nouveau_heap_alloc(heap, 2, &nv30->blit_vp, &nv30->blit_vp)) {
         while (heap->next && heap->size < 2) {
            struct nouveau_heap **evict = heap->next->priv;
            nouveau_heap_free(evict);
         }

         if (nouveau_heap_alloc(heap, 2, &nv30->blit_vp, &nv30->blit_vp))
            return NULL;
      }

      vp = nv30->blit_vp;
      if (vp) {
         struct nouveau_pushbuf *push = nv30->base.pushbuf;

         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1);
         PUSH_DATA (push, vp->start);
         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
         PUSH_DATA (push, 0x401f9c6c); /* mov o[hpos], a[0]; */
         PUSH_DATA (push, 0x0040000d);
         PUSH_DATA (push, 0x8106c083);
         PUSH_DATA (push, 0x6041ff80);
         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
         PUSH_DATA (push, 0x401f9c6c); /* mov o[tex0], a[8]; end; */
         PUSH_DATA (push, 0x0040080d);
         PUSH_DATA (push, 0x8106c083);
         PUSH_DATA (push, 0x6041ff9d);
      }
   }

   return vp;
}
예제 #15
0
static Bool
NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict)
{
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
	uint32_t pitch = exaGetPixmapPitch(pPix);
	nv_pict_surface_format_t *fmt;

	fmt = NV30_GetPictSurfaceFormat(pPict->format);
	if (!fmt) {
		ErrorF("AIII no format\n");
		return FALSE;
	}

	BEGIN_NV04(push, NV30_3D(RT_FORMAT), 3);
	PUSH_DATA (push, fmt->card_fmt); /* format */
	PUSH_DATA (push, pitch << 16 | pitch);
	PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), bo, 0,
			 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
	return TRUE;
}
예제 #16
0
static Bool
NV40_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PictFormatShort format)
{
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
	nv_pict_surface_format_t *fmt;

	fmt = NV40_GetPictSurfaceFormat(format);
	if (!fmt) {
		ErrorF("AIII no format\n");
		return FALSE;
	}

	BEGIN_NV04(push, NV30_3D(RT_FORMAT), 3);
	PUSH_DATA (push, NV30_3D_RT_FORMAT_TYPE_LINEAR |
			 NV30_3D_RT_FORMAT_ZETA_Z24S8 | fmt->card_fmt);
	PUSH_DATA (push, exaGetPixmapPitch(pPix));
	PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), bo, 0,
			 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
	return TRUE;
}
static void
nv30_draw_elements_inline_u16(struct nouveau_pushbuf *push, const uint16_t *map,
                              unsigned start, unsigned count)
{
   map += start;

   if (count & 1) {
      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
      PUSH_DATA (push, *map++);
   }

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

      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
      while (npush--) {
         PUSH_DATA (push, (map[1] << 16) | map[0]);
         map += 2;
      }
   }
}
static void
nv30_update_user_vbufs(struct nv30_context *nv30)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   uint32_t base, offset, size;
   int i;
   uint32_t written = 0;

   for (i = 0; i < nv30->vertex->num_elements; i++) {
      struct pipe_vertex_element *ve = &nv30->vertex->pipe[i];
      const int b = ve->vertex_buffer_index;
      struct pipe_vertex_buffer *vb = &nv30->vtxbuf[b];
      struct nv04_resource *buf = nv04_resource(vb->buffer);

      if (!(nv30->vbo_user & (1 << b)))
         continue;

      if (!vb->stride) {
         nv30_emit_vtxattr(nv30, vb, ve, i);
         continue;
      }
      nv30_vbuf_range(nv30, b, &base, &size);

      if (!(written & (1 << b))) {
         written |= 1 << b;
         nouveau_user_buffer_upload(&nv30->base, buf, base, size);
      }

      offset = vb->buffer_offset + ve->src_offset;

      BEGIN_NV04(push, NV30_3D(VTXBUF(i)), 1);
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP, buf, offset,
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD,
                       0, NV30_3D_VTXBUF_DMA1);
   }
   nv30->base.vbo_dirty = TRUE;
}
예제 #19
0
파일: nv30_push.c 프로젝트: DirectFB/mesa
static void
emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
{
   while (count) {
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
      unsigned size = ctx->vertex_words * push;

      BEGIN_NI04(ctx->push, NV30_3D(VERTEX_DATA), size);

      ctx->translate->run(ctx->translate, start, push, 0, 0, ctx->push->cur);
      ctx->push->cur += size;
      count -= push;
      start += push;
   }
}
예제 #20
0
static void
nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
{
   struct nv30_render *r = nv30_render(render);
   struct nv30_context *nv30 = r->nv30;
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   unsigned fn = nr >> 8, pn = nr & 0xff;
   unsigned ps = fn + (pn ? 1 : 0);
   unsigned i;

   BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
   for (i = 0; i < r->vertex_info.num_attribs; i++) {
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                       nv04_resource(r->buffer), r->offset + r->vtxptr[i],
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
   }

   if (!nv30_state_validate(nv30, FALSE))
      return;

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, r->prim);

   BEGIN_NI04(push, NV30_3D(VB_VERTEX_BATCH), ps);
   while (fn--) {
      PUSH_DATA (push, 0xff000000 | start);
      start += 256;
   }

   if (pn)
      PUSH_DATA (push, ((pn - 1) << 24) | start);

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
   PUSH_RESET(push, BUFCTX_VTXTMP);
}
static void
nv30_draw_elements_inline_u32(struct nouveau_pushbuf *push, const uint32_t *map,
                              unsigned start, unsigned count)
{
   map += start;

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

      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U32), nr);
      PUSH_DATAp(push, map, nr);

      map += nr;
      count -= nr;
   }
}
static void
nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_screen *screen = nv30->screen;
   struct nv30_query *q = nv30_query(pq);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;

   q->qo[1] = nv30_query_object_new(screen);
   if (q->qo[1]) {
      BEGIN_NV04(push, NV30_3D(QUERY_GET), 1);
      PUSH_DATA (push, (q->report << 24) | q->qo[1]->hw->start);
   }

   if (q->enable) {
      BEGIN_NV04(push, SUBC_3D(q->enable), 1);
      PUSH_DATA (push, 0);
   }
   PUSH_KICK (push);
}
예제 #23
0
static void
nv30_render_draw_elements(struct vbuf_render *render,
                          const ushort *indices, uint count)
{
   struct nv30_render *r = nv30_render(render);
   struct nv30_context *nv30 = r->nv30;
   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
   unsigned i;

   BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
   for (i = 0; i < r->vertex_info.num_attribs; i++) {
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                       nv04_resource(r->buffer), r->offset + r->vtxptr[i],
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
   }

   if (!nv30_state_validate(nv30, FALSE))
      return;

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, r->prim);

   if (count & 1) {
      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
      PUSH_DATA (push, *indices++);
   }

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

      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
      while (npush--) {
         PUSH_DATA(push, (indices[1] << 16) | indices[0]);
         indices += 2;
      }
   }

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
   PUSH_RESET(push, BUFCTX_VTXTMP);
}
void
nv30_fragtex_validate(struct nv30_context *nv30)
{
   struct pipe_screen *pscreen = &nv30->screen->base.base;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   unsigned dirty = nv30->fragprog.dirty_samplers;

   while (dirty) {
      unsigned unit = ffs(dirty) - 1;
      struct nv30_sampler_view *sv = (void *)nv30->fragprog.textures[unit];
      struct nv30_sampler_state *ss = nv30->fragprog.samplers[unit];

      PUSH_RESET(push, BUFCTX_FRAGTEX(unit));

      if (ss && sv) {
         const struct nv30_texfmt *fmt = nv30_texfmt(pscreen, sv->pipe.format);
         struct pipe_resource *pt = sv->pipe.texture;
         struct nv30_miptree *mt = nv30_miptree(pt);
         unsigned min_lod, max_lod;
         u32 filter = sv->filt | (ss->filt & sv->filt_mask);
         u32 format = sv->fmt | ss->fmt;
         u32 enable = ss->en;

         /* handle base_level when not using a mip filter, min/max level
          * is unfortunately ignored by the hardware otherwise
          */
         if (ss->pipe.min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
            if (sv->base_lod)
               filter += 0x00020000; /* N/L -> NMN/LMN */
            max_lod = sv->base_lod;
            min_lod = sv->base_lod;
         } else {
            max_lod = MIN2(ss->max_lod + sv->base_lod, sv->high_lod);
            min_lod = MIN2(ss->min_lod + sv->base_lod, max_lod);
         }

         if (eng3d->oclass >= NV40_3D_CLASS) {
            /* this is a tad stupid of the hardware, but there's no non-rcomp
             * z16/z24 texture formats to be had, we have to suffer and lose
             * some precision to handle this case.
             */
            if (ss->pipe.compare_mode != PIPE_TEX_COMPARE_R_TO_TEXTURE) {
               if (fmt->nv40 == NV40_3D_TEX_FORMAT_FORMAT_Z16)
                  format |= NV40_3D_TEX_FORMAT_FORMAT_A8L8;
               else
               if (fmt->nv40 == NV40_3D_TEX_FORMAT_FORMAT_Z24)
                  format |= NV40_3D_TEX_FORMAT_FORMAT_A16L16;
               else
                  format |= fmt->nv40;
            } else {
               format |= fmt->nv40;
            }

            enable |= (min_lod << 19) | (max_lod << 7);
            enable |= NV40_3D_TEX_ENABLE_ENABLE;

            BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1);
            PUSH_DATA (push, sv->npot_size1);
         } else {
            /* this is a tad stupid of the hardware, but there's no non-rcomp
             * z16/z24 texture formats to be had, we have to suffer and lose
             * some precision to handle this case.
             */
            if (ss->pipe.compare_mode != PIPE_TEX_COMPARE_R_TO_TEXTURE) {
               if (fmt->nv30 == NV30_3D_TEX_FORMAT_FORMAT_Z16) {
                  if (ss->pipe.normalized_coords)
                     format |= NV30_3D_TEX_FORMAT_FORMAT_A8L8;
                  else
                     format |= NV30_3D_TEX_FORMAT_FORMAT_A8L8_RECT;
               } else
               if (fmt->nv30 == NV30_3D_TEX_FORMAT_FORMAT_Z24) {
                  if (ss->pipe.normalized_coords)
                     format |= NV30_3D_TEX_FORMAT_FORMAT_HILO16;
                  else
                     format |= NV30_3D_TEX_FORMAT_FORMAT_HILO16_RECT;
               } else {
                  if (ss->pipe.normalized_coords)
                     format |= fmt->nv30;
                  else
                     format |= fmt->nv30_rect;
               }
            } else {
               if (ss->pipe.normalized_coords)
                  format |= fmt->nv30;
               else
                  format |= fmt->nv30_rect;
            }

            enable |= NV30_3D_TEX_ENABLE_ENABLE;
            enable |= (min_lod << 18) | (max_lod << 6);
         }

         BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8);
         PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), BUFCTX_FRAGTEX(unit),
                          mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
         PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), BUFCTX_FRAGTEX(unit),
                          mt->base.bo, format, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD,
                          NV30_3D_TEX_FORMAT_DMA0,
                          NV30_3D_TEX_FORMAT_DMA1);
         PUSH_DATA (push, sv->wrap | (ss->wrap & sv->wrap_mask));
         PUSH_DATA (push, enable);
         PUSH_DATA (push, sv->swz);
         PUSH_DATA (push, filter);
         PUSH_DATA (push, sv->npot_size0);
         PUSH_DATA (push, ss->bcol);
         BEGIN_NV04(push, NV30_3D(TEX_FILTER_OPTIMIZATION(unit)), 1);
         PUSH_DATA (push, nv30->config.filter);
      } else {
         BEGIN_NV04(push, NV30_3D(TEX_ENABLE(unit)), 1);
         PUSH_DATA (push, 0);
      }

      dirty &= ~(1 << unit);
   }

   nv30->fragprog.dirty_samplers = 0;
}
예제 #25
0
static boolean
nv30_render_validate(struct nv30_context *nv30)
{
   struct nv30_render *r = nv30_render(nv30->draw->render);
   struct nv30_rasterizer_stateobj *rast = nv30->rast;
   struct pipe_screen *pscreen = &nv30->screen->base.base;
   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nv30_vertprog *vp = nv30->vertprog.program;
   struct vertex_info *vinfo = &r->vertex_info;
   unsigned vp_attribs = 0;
   unsigned vp_results = 0;
   unsigned attrib = 0;
   unsigned pntc;
   int i;

   if (!r->vertprog) {
      struct nouveau_heap *heap = nv30_screen(pscreen)->vp_exec_heap;
      if (nouveau_heap_alloc(heap, 16, &r->vertprog, &r->vertprog)) {
         while (heap->next && heap->size < 16) {
            struct nouveau_heap **evict = heap->next->priv;
            nouveau_heap_free(evict);
         }

         if (nouveau_heap_alloc(heap, 16, &r->vertprog, &r->vertprog))
            return FALSE;
      }
   }

   vinfo->num_attribs = 0;
   vinfo->size = 0;

   /* setup routing for all necessary vp outputs */
   for (i = 0; i < vp->info.num_outputs && attrib < 16; i++) {
      uint semantic = vp->info.output_semantic_name[i];
      uint index = vp->info.output_semantic_index[i];
      if (vroute_add(r, attrib, semantic, &index)) {
         vp_attribs |= (1 << attrib++);
         vp_results |= index;
      }
   }

   /* setup routing for replaced point coords not written by vp */
   if (rast && rast->pipe.point_quad_rasterization)
      pntc = rast->pipe.sprite_coord_enable & 0x000002ff;
   else
      pntc = 0;

   while (pntc && attrib < 16) {
      uint index = ffs(pntc) - 1; pntc &= ~(1 << index);
      if (vroute_add(r, attrib, TGSI_SEMANTIC_TEXCOORD, &index)) {
         vp_attribs |= (1 << attrib++);
         vp_results |= index;
      }
   }

   /* modify vertex format for correct stride, and stub out unused ones */
   BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1);
   PUSH_DATA (push, r->vertprog->start);
   r->vtxprog[attrib - 1][3] |= 1;
   for (i = 0; i < attrib; i++) {
      BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
      PUSH_DATAp(push, r->vtxprog[i], 4);
      r->vtxfmt[i] |= vinfo->size << 8;
   }
   for (; i < 16; i++)
      r->vtxfmt[i]  = NV30_3D_VTXFMT_TYPE_V32_FLOAT;

   BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 1.0);

   BEGIN_NV04(push, NV30_3D(VTXFMT(0)), 16);
   PUSH_DATAp(push, r->vtxfmt, 16);

   BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1);
   PUSH_DATA (push, r->vertprog->start);
   BEGIN_NV04(push, NV30_3D(ENGINE), 1);
   PUSH_DATA (push, 0x00000103);
   if (eng3d->oclass >= NV40_3D_CLASS) {
      BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2);
      PUSH_DATA (push, vp_attribs);
      PUSH_DATA (push, vp_results);
   }

   vinfo->size /= 4;
   return TRUE;
}
예제 #26
0
파일: nv30_clear.c 프로젝트: DirectFB/mesa
static void
nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
                         unsigned buffers, double depth, unsigned stencil,
                         unsigned x, unsigned y, unsigned w, unsigned h)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_surface *sf = nv30_surface(ps);
   struct nv30_miptree *mt = nv30_miptree(ps->texture);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nouveau_pushbuf_refn refn;
   uint32_t rt_format, mode = 0;

   rt_format = nv30_format(pipe->screen, ps->format)->hw;
   if (util_format_get_blocksize(ps->format) == 4)
      rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
   else
      rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;

   if (nv30_miptree(ps->texture)->swizzled) {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      rt_format |= util_logbase2(sf->width) << 16;
      rt_format |= util_logbase2(sf->height) << 24;
   } else {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
   }

   if (buffers & PIPE_CLEAR_DEPTH)
      mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
   if (buffers & PIPE_CLEAR_STENCIL)
      mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;

   refn.bo = mt->base.bo;
   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
   if (nouveau_pushbuf_space(push, 32, 1, 0) ||
       nouveau_pushbuf_refn (push, &refn, 1))
      return;

   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
   PUSH_DATA (push, sf->width << 16);
   PUSH_DATA (push, sf->height << 16);
   PUSH_DATA (push, rt_format);
   if (eng3d->oclass < NV40_3D_CLASS) {
      BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 1);
      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
   } else {
      BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
      PUSH_DATA (push, sf->pitch);
   }
   BEGIN_NV04(push, NV30_3D(ZETA_OFFSET), 1);
   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (w << 16) | x);
   PUSH_DATA (push, (h << 16) | y);

   BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 1);
   PUSH_DATA (push, pack_zeta(ps->format, depth, stencil));
   BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
   PUSH_DATA (push, mode);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
예제 #27
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;
}
예제 #28
0
파일: nv30_push.c 프로젝트: DirectFB/mesa
void
nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
{
   struct push_context ctx;
   unsigned i, index_size;
   boolean apply_bias = info->indexed && info->index_bias;

   ctx.push = nv30->base.pushbuf;
   ctx.translate = nv30->vertex->translate;
   ctx.packet_vertex_limit = nv30->vertex->vtx_per_packet_max;
   ctx.vertex_words = nv30->vertex->vtx_size;

   for (i = 0; i < nv30->num_vtxbufs; ++i) {
      uint8_t *data;
      struct pipe_vertex_buffer *vb = &nv30->vtxbuf[i];
      struct nv04_resource *res = nv04_resource(vb->buffer);

      if (!vb->buffer && !vb->user_buffer) {
         continue;
      }

      data = nouveau_resource_map_offset(&nv30->base, res,
                                         vb->buffer_offset, NOUVEAU_BO_RD);

      if (apply_bias)
         data += info->index_bias * vb->stride;

      ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
   }

   if (info->indexed) {
      if (nv30->idxbuf.buffer)
         ctx.idxbuf = nouveau_resource_map_offset(&nv30->base,
            nv04_resource(nv30->idxbuf.buffer), nv30->idxbuf.offset,
            NOUVEAU_BO_RD);
      else
         ctx.idxbuf = nv30->idxbuf.user_buffer;
      if (!ctx.idxbuf) {
         nv30_state_release(nv30);
         return;
      }
      index_size = nv30->idxbuf.index_size;
      ctx.primitive_restart = info->primitive_restart;
      ctx.restart_index = info->restart_index;
   } else {
      ctx.idxbuf = NULL;
      index_size = 0;
      ctx.primitive_restart = FALSE;
      ctx.restart_index = 0;
   }

   if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
      BEGIN_NV04(ctx.push, NV40_3D(PRIM_RESTART_ENABLE), 2);
      PUSH_DATA (ctx.push, info->primitive_restart);
      PUSH_DATA (ctx.push, info->restart_index);
      nv30->state.prim_restart = info->primitive_restart;
   }

   ctx.prim = nv30_prim_gl(info->mode);

   PUSH_RESET(ctx.push, BUFCTX_IDXBUF);
   BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (ctx.push, ctx.prim);
   switch (index_size) {
   case 0:
      emit_vertices_seq(&ctx, info->start, info->count);
      break;
   case 1:
      emit_vertices_i08(&ctx, info->start, info->count);
      break;
   case 2:
      emit_vertices_i16(&ctx, info->start, info->count);
      break;
   case 4:
      emit_vertices_i32(&ctx, info->start, info->count);
      break;
   default:
      assert(0);
      break;
   }
   BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (ctx.push, NV30_3D_VERTEX_BEGIN_END_STOP);

   if (info->indexed)
      nouveau_resource_unmap(nv04_resource(nv30->idxbuf.buffer));

   for (i = 0; i < nv30->num_vtxbufs; ++i) {
      if (nv30->vtxbuf[i].buffer) {
         nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer));
      }
   }

   nv30_state_release(nv30);
}
예제 #29
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;
}
예제 #30
0
static Bool
NV40EXAPictTexture(NVPtr pNv, PixmapPtr pPix, PicturePtr pPict, int unit)
{
	unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR;
	struct nouveau_pushbuf *push = pNv->pushbuf;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
	nv_pict_texture_format_t *fmt;

	fmt = NV40_GetPictTextureFormat(pPict->format);
	if (!fmt)
		return FALSE;

	BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8);
	PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), bo, 0, reloc);
	PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), bo, fmt->card_fmt |
			 NV40_3D_TEX_FORMAT_LINEAR |
			 NV30_3D_TEX_FORMAT_DIMS_2D | 0x8000 |
			 NV30_3D_TEX_FORMAT_NO_BORDER |
			 (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT),
			 reloc | NOUVEAU_BO_OR,
			 NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1);
	if (pPict->repeat) {
		switch(pPict->repeatType) {
		case RepeatPad:
			PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP | 
					 NV30_3D_TEX_WRAP_T_CLAMP |
					 NV30_3D_TEX_WRAP_R_CLAMP);
			break;
		case RepeatReflect:
			PUSH_DATA (push, NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT |
					 NV30_3D_TEX_WRAP_T_MIRRORED_REPEAT |
					 NV30_3D_TEX_WRAP_R_MIRRORED_REPEAT);
			break;
		case RepeatNormal:
		default:
			PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT |
					 NV30_3D_TEX_WRAP_T_REPEAT |
					 NV30_3D_TEX_WRAP_R_REPEAT);
			break;
		}
	} else {
		PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_BORDER |
				 NV30_3D_TEX_WRAP_T_CLAMP_TO_BORDER |
				 NV30_3D_TEX_WRAP_R_CLAMP_TO_BORDER);
	}
	PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE);
	PUSH_DATA (push, fmt->card_swz);
	if (pPict->filter == PictFilterBilinear) {
		PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR |
				 NV30_3D_TEX_FILTER_MAG_LINEAR | 0x3fd6);
	} else {
		PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST |
				 NV30_3D_TEX_FILTER_MAG_NEAREST | 0x3fd6);
	}
	PUSH_DATA (push, (pPix->drawable.width << 16) | pPix->drawable.height);
	PUSH_DATA (push, 0); /* border ARGB */
	BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1);
	PUSH_DATA (push, (1 << NV40_3D_TEX_SIZE1_DEPTH__SHIFT) |
			 (uint32_t)exaGetPixmapPitch(pPix));

	BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 17);
	PUSH_DATA (push, unit * 4);
	if (pPict->transform) {
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[0][0]));
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[0][1]));
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[0][2]));
		PUSH_DATAf(push, 0);
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[1][0]));
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[1][1]));
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[1][2]));
		PUSH_DATAf(push, 0);
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[2][0]));
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[2][1]));
		PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[2][2]));
		PUSH_DATAf(push, 0);
	} else {
		PUSH_DATAf(push, 1.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 1.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 0.0);
		PUSH_DATAf(push, 1.0);
		PUSH_DATAf(push, 0.0);
	}
	PUSH_DATAf(push, 1.0 / pPix->drawable.width);
	PUSH_DATAf(push, 1.0 / pPix->drawable.height);
	PUSH_DATAf(push, 0.0);
	PUSH_DATAf(push, 1.0);

	return TRUE;
}