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); }
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; }
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; }
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*/); } }
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; }