Exemplo n.º 1
0
static Bool
check_texture(PicturePtr pict)
{
	int w, h;

	if (!pict->pDrawable)
		NOUVEAU_FALLBACK("Solid and gradient pictures unsupported\n");

	w = pict->pDrawable->width;
	h = pict->pDrawable->height;

	if (w > 2046 || h > 2046)
		NOUVEAU_FALLBACK("picture too large, %dx%d\n", w, h);

	if (!get_tex_format(pict))
		return FALSE;

	if (pict->filter != PictFilterNearest &&
	    pict->filter != PictFilterBilinear)
		return FALSE;

	/* We cannot repeat on NV10 because NPOT textures do not
	 * support this. unfortunately. */
	if (pict->repeat != RepeatNone)
		/* we can repeat 1x1 textures */
		if (!(w == 1 && h == 1))
			return FALSE;

	return TRUE;
}
Exemplo n.º 2
0
static void
nouveau_render_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
		       struct gl_renderbuffer_attachment *att)
{
	struct gl_renderbuffer *rb = att->Renderbuffer;
	struct gl_texture_image *ti =
		att->Texture->Image[att->CubeMapFace][att->TextureLevel];

	/* Allocate a renderbuffer object for the texture if we
	 * haven't already done so. */
	if (!rb) {
		rb = nouveau_renderbuffer_new(ctx, ~0);
		assert(rb);

		rb->AllocStorage = NULL;
		_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
	}

	/* Update the renderbuffer fields from the texture. */
	set_renderbuffer_format(rb, get_tex_format(ti));
	rb->Width = ti->Width;
	rb->Height = ti->Height;
	nouveau_surface_ref(&to_nouveau_teximage(ti)->surface,
			    &to_nouveau_renderbuffer(rb)->surface);

	context_dirty(ctx, FRAMEBUFFER);
}
Exemplo n.º 3
0
void
nv04_emit_tex_obj(struct gl_context *ctx, int emit)
{
	struct nv04_context *nv04 = to_nv04_context(ctx);
	const int i = emit - NOUVEAU_STATE_TEX_OBJ0;
	struct nouveau_surface *s;
	uint32_t format = 0xa0, filter = 0x1010;

	if (ctx->Texture.Unit[i]._ReallyEnabled) {
		struct gl_texture_object *t = ctx->Texture.Unit[i]._Current;
		struct gl_texture_image *ti = t->Image[0][t->BaseLevel];
		int lod_max = 1, lod_bias = 0;

		if (!nouveau_texture_validate(ctx, t))
			return;

		s = &to_nouveau_texture(t)->surfaces[t->BaseLevel];

		if (t->Sampler.MinFilter != GL_NEAREST &&
		    t->Sampler.MinFilter != GL_LINEAR) {
			lod_max = CLAMP(MIN2(t->Sampler.MaxLod, t->_MaxLambda),
					0, 15) + 1;

			lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias +
					 t->Sampler.LodBias, -16, 15) * 8;
		}

		format |= nvgl_wrap_mode(t->Sampler.WrapT) << 28 |
			nvgl_wrap_mode(t->Sampler.WrapS) << 24 |
			ti->HeightLog2 << 20 |
			ti->WidthLog2 << 16 |
			lod_max << 12 |
			get_tex_format(ti);

		filter |= log2i(t->Sampler.MaxAnisotropy) << 31 |
			nvgl_filter_mode(t->Sampler.MagFilter) << 28 |
			log2i(t->Sampler.MaxAnisotropy) << 27 |
			nvgl_filter_mode(t->Sampler.MinFilter) << 24 |
			(lod_bias & 0xff) << 16;

	} else {
		s = &to_nv04_context(ctx)->dummy_texture;

		format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT |
			NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT |
			1 << 12 |
			NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8;

		filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST |
			NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
	}

	nv04->texture[i] = s;
	nv04->format[i] = format;
	nv04->filter[i] = filter;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
static Bool
setup_texture(NVPtr pNv, int unit, PicturePtr pict, PixmapPtr pixmap)
{
	struct nouveau_pushbuf *push = pNv->pushbuf;
	struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap);
	unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
	unsigned h = pict->pDrawable->height;
	unsigned w = pict->pDrawable->width;
	unsigned format;

	format = NV10_3D_TEX_FORMAT_WRAP_T_CLAMP_TO_EDGE |
		 NV10_3D_TEX_FORMAT_WRAP_S_CLAMP_TO_EDGE |
		 log2i(w) << 20 | log2i(h) << 16 |
		 1 << 12 | /* lod == 1 */
		 get_tex_format(pNv, pict) |
		 0x50 /* UNK */;

	/* 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_NV04(push, NV10_3D(TEX_OFFSET(unit)), 1);
	PUSH_MTHDl(push, NV10_3D(TEX_OFFSET(unit)), bo, 0, reloc);
	BEGIN_NV04(push, NV10_3D(TEX_FORMAT(unit)), 1);
	PUSH_MTHDs(push, NV10_3D(TEX_FORMAT(unit)), bo, format, reloc,
			 NV10_3D_TEX_FORMAT_DMA0,
			 NV10_3D_TEX_FORMAT_DMA1);
	BEGIN_NV04(push, NV10_3D(TEX_ENABLE(unit)), 1 );
	PUSH_DATA (push, NV10_3D_TEX_ENABLE_ENABLE);
	BEGIN_NV04(push, NV10_3D(TEX_NPOT_PITCH(unit)), 1);
	PUSH_DATA (push, exaGetPixmapPitch(pixmap) << 16);
	BEGIN_NV04(push, NV10_3D(TEX_NPOT_SIZE(unit)), 1);
	PUSH_DATA (push, (w << 16) | h);
	BEGIN_NV04(push, NV10_3D(TEX_FILTER(unit)), 1);
	if (pict->filter == PictFilterNearest)
		PUSH_DATA(push, NV10_3D_TEX_FILTER_MAGNIFY_NEAREST |
				NV10_3D_TEX_FILTER_MINIFY_NEAREST);
	else
		PUSH_DATA(push, NV10_3D_TEX_FILTER_MAGNIFY_LINEAR |
				NV10_3D_TEX_FILTER_MINIFY_LINEAR);
	if (pict->transform) {
		BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(unit)), 1);
		PUSH_DATA (push, 1);
		BEGIN_NV04(push, NV10_3D(TEX_MATRIX(unit, 0)), 16);
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[0][0]));
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[0][1]));
		PUSH_DATAf(push, 0.f);
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[0][2]));
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[1][0]));
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[1][1]));
		PUSH_DATAf(push, 0.f);
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[1][2]));
		PUSH_DATAf(push, 0.0f);
		PUSH_DATAf(push, 0.0f);
		PUSH_DATAf(push, 0.0f);
		PUSH_DATAf(push, 0.0f);
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[2][0]));
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[2][1]));
		PUSH_DATAf(push, 0.0f);
		PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[2][2]));
	} else {
		BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(unit)), 1);
		PUSH_DATA (push, 0);
	}

	return TRUE;
}
Exemplo n.º 6
0
void
nv04_emit_tex_obj(struct gl_context *ctx, int emit)
{
	const int i = emit - NOUVEAU_STATE_TEX_OBJ0;
	struct nouveau_channel *chan = context_chan(ctx);
	struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
	struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i);
	const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM;
	struct nouveau_surface *s;
	uint32_t format = 0xa0, filter = 0x1010;

	if (i && !nv04_mtex_engine(fahrenheit))
		return;

	if (ctx->Texture.Unit[i]._ReallyEnabled) {
		struct gl_texture_object *t = ctx->Texture.Unit[i]._Current;
		struct gl_texture_image *ti = t->Image[0][t->BaseLevel];
		int lod_max = 1, lod_bias = 0;

		if (!nouveau_texture_validate(ctx, t))
			return;

		s = &to_nouveau_texture(t)->surfaces[t->BaseLevel];

		if (t->MinFilter != GL_NEAREST &&
		    t->MinFilter != GL_LINEAR) {
			lod_max = CLAMP(MIN2(t->MaxLod, t->_MaxLambda),
					0, 15) + 1;

			lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias +
					 t->LodBias, -16, 15) * 8;
		}

		format |= nvgl_wrap_mode(t->WrapT) << 28 |
			nvgl_wrap_mode(t->WrapS) << 24 |
			ti->HeightLog2 << 20 |
			ti->WidthLog2 << 16 |
			lod_max << 12 |
			get_tex_format(ti);

		filter |= log2i(t->MaxAnisotropy) << 31 |
			nvgl_filter_mode(t->MagFilter) << 28 |
			log2i(t->MaxAnisotropy) << 27 |
			nvgl_filter_mode(t->MinFilter) << 24 |
			(lod_bias & 0xff) << 16;

	} else {
		s = &to_nv04_context(ctx)->dummy_texture;

		format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT |
			NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT |
			1 << 12 |
			NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8;

		filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST |
			NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
	}

	if (nv04_mtex_engine(fahrenheit)) {
		nouveau_bo_markl(bctx, fahrenheit,
				 NV04_MULTITEX_TRIANGLE_OFFSET(i),
				 s->bo, s->offset, bo_flags);

		nouveau_bo_mark(bctx, fahrenheit,
				NV04_MULTITEX_TRIANGLE_FORMAT(i),
				s->bo, format, 0,
				NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A,
				NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B,
				bo_flags | NOUVEAU_BO_OR);

		BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FILTER(i), 1);
		OUT_RING(chan, filter);

	} else {
		nouveau_bo_markl(bctx, fahrenheit,
				 NV04_TEXTURED_TRIANGLE_OFFSET,
				 s->bo, s->offset, bo_flags);

		nouveau_bo_mark(bctx, fahrenheit,
				NV04_TEXTURED_TRIANGLE_FORMAT,
				s->bo, format, 0,
				NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A,
				NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B,
				bo_flags | NOUVEAU_BO_OR);

		BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1);
		OUT_RING(chan, 0);

		BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1);
		OUT_RING(chan, filter);
	}
}