static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
{
	struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
	struct pipe_texture *pt = &nv04mt->base;

	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3);
	OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
	OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
	OUT_RING(nv04->sampler[unit]->filter);
}
Beispiel #2
0
static Bool
setup_texture(NVPtr pNv, int unit, PicturePtr pict, PixmapPtr pixmap)
{
	struct nouveau_channel *chan = pNv->chan;
	struct nouveau_grobj *celsius = pNv->Nv3D;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap);
	unsigned tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
	long w = pict->pDrawable->width,
	     h = pict->pDrawable->height;
	unsigned int txfmt =
		NV10TCL_TX_FORMAT_WRAP_T_CLAMP_TO_EDGE |
		NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE |
		log2i(w) << 20 | log2i(h) << 16 |
		1 << 12 | /* lod == 1 */
		get_tex_format(pict) |
		0x50 /* UNK */;

	BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(unit), 1);
	if (OUT_RELOCl(chan, bo, 0, tex_reloc))
		return FALSE;

	if (pict->repeat == RepeatNone) {
		/* NPOT_SIZE expects an even number for width, we can
		 * round up uneven numbers here because EXA always
		 * gives 64 byte aligned pixmaps and for all formats
		 * we support 64 bytes represents an even number of
		 * pixels
		 */
		w = (w + 1) &~ 1;

		BEGIN_RING(chan, celsius, NV10TCL_TX_NPOT_PITCH(unit), 1);
		OUT_RING  (chan, exaGetPixmapPitch(pixmap) << 16);

		BEGIN_RING(chan, celsius, NV10TCL_TX_NPOT_SIZE(unit), 1);
		OUT_RING  (chan, w << 16 | h);
	}

	BEGIN_RING(chan, celsius, NV10TCL_TX_FORMAT(unit), 1 );
	if (OUT_RELOCd(chan, bo, txfmt, tex_reloc | NOUVEAU_BO_OR,
		       NV10TCL_TX_FORMAT_DMA0, NV10TCL_TX_FORMAT_DMA1))
		return FALSE;

	BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(unit), 1 );
	OUT_RING  (chan, NV10TCL_TX_ENABLE_ENABLE);

	BEGIN_RING(chan, celsius, NV10TCL_TX_FILTER(unit), 1);
	if (pict->filter == PictFilterNearest)
		OUT_RING(chan, (NV10TCL_TX_FILTER_MAGNIFY_NEAREST |
				NV10TCL_TX_FILTER_MINIFY_NEAREST));
	else
		OUT_RING(chan, (NV10TCL_TX_FILTER_MAGNIFY_LINEAR |
				NV10TCL_TX_FILTER_MINIFY_LINEAR));

	return TRUE;
}
Beispiel #3
0
static Bool
NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit)
{
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_channel *chan = pNv->chan;
	struct nouveau_grobj *rankine = pNv->Nv3D;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
	nv_pict_texture_format_t *fmt;
	uint32_t card_filter, card_repeat;
	uint32_t tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
	NV30EXA_STATE;

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

	card_repeat = 3; /* repeatNone */

	if (pPict->filter == PictFilterBilinear)
		card_filter = 2;
	else
		card_filter = 1;

	BEGIN_RING(chan, rankine, NV34TCL_TX_OFFSET(unit), 8);
	if (OUT_RELOCl(chan, bo, 0, tex_reloc) ||
	    OUT_RELOCd(chan, bo, NV34TCL_TX_FORMAT_DIMS_2D | (1 << 16) | 8 |
		       (fmt->card_fmt << NV34TCL_TX_FORMAT_FORMAT_SHIFT) |
		       (log2i(pPix->drawable.width) <<
			NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT) |
		       (log2i(pPix->drawable.height) <<
			NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT),
		       tex_reloc | NOUVEAU_BO_OR,
		       NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1))
		return FALSE;
	OUT_RING  (chan, (card_repeat << NV34TCL_TX_WRAP_S_SHIFT) |
			(card_repeat << NV34TCL_TX_WRAP_T_SHIFT) |
			(card_repeat << NV34TCL_TX_WRAP_R_SHIFT));
	OUT_RING  (chan, NV34TCL_TX_ENABLE_ENABLE);
	OUT_RING  (chan, (((uint32_t)exaGetPixmapPitch(pPix)) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT ) | 
			fmt->card_swz);

	OUT_RING  (chan, (card_filter << NV34TCL_TX_FILTER_MINIFY_SHIFT) /* min */ |
			(card_filter << NV34TCL_TX_FILTER_MAGNIFY_SHIFT) /* mag */ |
			0x2000 /* engine lock */);
	OUT_RING  (chan, (pPix->drawable.width << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pPix->drawable.height);
	OUT_RING  (chan, 0); /* border ARGB */

	state->unit[unit].width		= (float)pPix->drawable.width;
	state->unit[unit].height	= (float)pPix->drawable.height;
	state->unit[unit].transform	= pPict->transform;

	return TRUE;
}
Beispiel #4
0
static void
nv20_fragtex_build(struct nv20_context *nv20, int unit)
{
#if 0
	struct nv20_sampler_state *ps = nv20->tex_sampler[unit];
	struct nv20_miptree *nv20mt = nv20->tex_miptree[unit];
	struct pipe_texture *pt = &nv20mt->base;
	struct nv20_texture_format *tf;
	uint32_t txf, txs, txp;

	tf = nv20_fragtex_format(pt->format);
	if (!tf || !tf->defined) {
		NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format);
		return;
	}

	txf  = tf->format << 8;
	txf |= (pt->last_level + 1) << 16;
	txf |= log2i(pt->width[0]) << 20;
	txf |= log2i(pt->height[0]) << 24;
	txf |= log2i(pt->depth[0]) << 28;
	txf |= 8;

	switch (pt->target) {
	case PIPE_TEXTURE_CUBE:
		txf |= NV10TCL_TX_FORMAT_CUBE_MAP;
		/* fall-through */
	case PIPE_TEXTURE_2D:
		txf |= (2<<4);
		break;
	case PIPE_TEXTURE_1D:
		txf |= (1<<4);
		break;
	default:
		NOUVEAU_ERR("Unknown target %d\n", pt->target);
		return;
	}

	BEGIN_RING(kelvin, NV10TCL_TX_OFFSET(unit), 8);
	OUT_RELOCl(nv20mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
	OUT_RELOCd(nv20mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
	OUT_RING  (ps->wrap);
	OUT_RING  (0x40000000); /* enable */
	OUT_RING  (txs);
	OUT_RING  (ps->filt | 0x2000 /* magic */);
	OUT_RING  ((pt->width[0] << 16) | pt->height[0]);
	OUT_RING  (ps->bcol);
#endif
}
void
nv04_emit_hw_state(struct nv04_context *nv04)
{
	int i;

	if (nv04->dirty & NV04_NEW_VERTPROG) {
		//nv04_vertprog_bind(nv04, nv04->vertprog.current);
		nv04->dirty &= ~NV04_NEW_VERTPROG;
	}

	if (nv04->dirty & NV04_NEW_FRAGPROG) {
		nv04_fragprog_bind(nv04, nv04->fragprog.current);
		nv04->dirty &= ~NV04_NEW_FRAGPROG;
		nv04->dirty_samplers |= (1<<10);
		nv04->dirty_samplers = 0;
	}

	if (nv04->dirty & NV04_NEW_CONTROL) {
		nv04->dirty &= ~NV04_NEW_CONTROL;

		BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
		OUT_RING(nv04->dsa->control);
	}

	if (nv04->dirty & NV04_NEW_BLEND) {
		nv04->dirty &= ~NV04_NEW_BLEND;

		nv04_emit_blend(nv04);
	}

	if (nv04->dirty & NV04_NEW_VTXARRAYS) {
		nv04->dirty &= ~NV04_NEW_VTXARRAYS;
		nv04_vertex_layout(nv04);
	}

	if (nv04->dirty & NV04_NEW_SAMPLER) {
		nv04->dirty &= ~NV04_NEW_SAMPLER;

		nv04_emit_sampler(nv04, 0);
	}

	if (nv04->dirty & NV04_NEW_VIEWPORT) {
		nv04->dirty &= ~NV04_NEW_VIEWPORT;
//		nv04_state_emit_viewport(nv04);
	}

 	if (nv04->dirty & NV04_NEW_FRAMEBUFFER) {
		nv04->dirty &= ~NV04_NEW_FRAMEBUFFER;
		nv04_state_emit_framebuffer(nv04);
	}

	/* Emit relocs for every referenced buffer.
	 * This is to ensure the bufmgr has an accurate idea of how
	 * the buffer is used.  This isn't very efficient, but we don't
	 * seem to take a significant performance hit.  Will be improved
	 * at some point.  Vertex arrays are emitted by nv04_vbo.c
	 */

	/* Render target */
	unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch;
	unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch;

	BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
	OUT_RING(rt_pitch|(zeta_pitch<<16));
	OUT_RELOCl(nv04->rt, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
	if (nv04->zeta) {
		BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
		OUT_RELOCl(nv04->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
	}

	/* Texture images */
	for (i = 0; i < 1; i++) {
		if (!(nv04->fp_samplers & (1 << i)))
			continue;
		struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
		BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2);
		OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
		OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
	}
}
Beispiel #6
0
static Bool
NV40EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit)
{
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_channel *chan = pNv->chan;
	struct nouveau_grobj *curie = pNv->Nv3D;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
	unsigned tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
	nv_pict_texture_format_t *fmt;
	NV40EXA_STATE;

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

	BEGIN_RING(chan, curie, NV40TCL_TEX_OFFSET(unit), 8);
	if (OUT_RELOCl(chan, bo, 0, tex_reloc) ||
	    OUT_RELOCd(chan, bo, fmt->card_fmt | NV40TCL_TEX_FORMAT_LINEAR |
		       NV40TCL_TEX_FORMAT_DIMS_2D | 0x8000 |
		       NV40TCL_TEX_FORMAT_NO_BORDER |
		       (1 << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT),
		       tex_reloc | NOUVEAU_BO_OR,
		       NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1))
		return FALSE;

	if (pPict->repeat) {
		switch(pPict->repeatType) {
		case RepeatPad:
			OUT_RING  (chan, NV40TCL_TEX_WRAP_S_CLAMP | 
					 NV40TCL_TEX_WRAP_T_CLAMP |
					 NV40TCL_TEX_WRAP_R_CLAMP);
			break;
		case RepeatReflect:
			OUT_RING  (chan, NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT |
					 NV40TCL_TEX_WRAP_T_MIRRORED_REPEAT |
					 NV40TCL_TEX_WRAP_R_MIRRORED_REPEAT);
			break;
		case RepeatNormal:
		default:
			OUT_RING  (chan, NV40TCL_TEX_WRAP_S_REPEAT |
					 NV40TCL_TEX_WRAP_T_REPEAT |
					 NV40TCL_TEX_WRAP_R_REPEAT);
			break;
		}
	} else {
		OUT_RING  (chan, NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER |
				 NV40TCL_TEX_WRAP_T_CLAMP_TO_BORDER |
				 NV40TCL_TEX_WRAP_R_CLAMP_TO_BORDER);
	}
	OUT_RING  (chan, NV40TCL_TEX_ENABLE_ENABLE);
	OUT_RING  (chan, fmt->card_swz);
	if (pPict->filter == PictFilterBilinear) {
		OUT_RING  (chan, NV40TCL_TEX_FILTER_MIN_LINEAR |
				 NV40TCL_TEX_FILTER_MAG_LINEAR | 0x3fd6);
	} else {
		OUT_RING  (chan, NV40TCL_TEX_FILTER_MIN_NEAREST |
				 NV40TCL_TEX_FILTER_MAG_NEAREST | 0x3fd6);
	}
	OUT_RING  (chan, (pPix->drawable.width << 16) | pPix->drawable.height);
	OUT_RING  (chan, 0); /* border ARGB */
	BEGIN_RING(chan, curie, NV40TCL_TEX_SIZE1(unit), 1);
	OUT_RING  (chan, (1 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) |
			 (uint32_t)exaGetPixmapPitch(pPix));

	state->unit[unit].width		= (float)pPix->drawable.width;
	state->unit[unit].height	= (float)pPix->drawable.height;
	state->unit[unit].transform	= pPict->transform;
	return TRUE;
}