diff options
Diffstat (limited to 'src/gallium/drivers/nv04/nv04_state_emit.c')
-rw-r--r-- | src/gallium/drivers/nv04/nv04_state_emit.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/gallium/drivers/nv04/nv04_state_emit.c b/src/gallium/drivers/nv04/nv04_state_emit.c new file mode 100644 index 0000000000..0ad40a092e --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state_emit.c @@ -0,0 +1,156 @@ +#include "nv04_context.h" +#include "nv04_state.h" + +static void nv04_vertex_layout(struct pipe_context* pipe) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = nv04->fragprog.current; + uint32_t src = 0; + int i; + struct vertex_info vinfo; + + memset(&vinfo, 0, sizeof(vinfo)); + + for (i = 0; i < fp->info.num_inputs; i++) { + switch (i) { + case TGSI_SEMANTIC_POSITION: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + case TGSI_SEMANTIC_COLOR: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + default: + case TGSI_SEMANTIC_GENERIC: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + case TGSI_SEMANTIC_FOG: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + } + } + draw_compute_vertex_size(&vinfo); +} + +static uint32_t nv04_blend_func(uint32_t f) +{ + switch ( f ) { + case PIPE_BLENDFACTOR_ZERO: return 0x1; + case PIPE_BLENDFACTOR_ONE: return 0x2; + case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4; + case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6; + case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8; + case PIPE_BLENDFACTOR_DST_COLOR: return 0x9; + case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB; + } + NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f); + return 0; +} + +static void nv04_emit_control(struct nv04_context* nv04) +{ + uint32_t control = nv04->dsa->control; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(control); +} + +static void nv04_emit_blend(struct nv04_context* nv04) +{ + uint32_t blend; + + blend=0x4; // texture MODULATE_ALPHA + blend|=0x20; // alpha is MSB + blend|=(2<<6); // flat shading + blend|=(1<<8); // persp correct + blend|=(0<<16); // no fog + blend|=(nv04->blend->b_enable<<20); + blend|=(nv04_blend_func(nv04->blend->b_src)<<24); + blend|=(nv04_blend_func(nv04->blend->b_dst)<<28); + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING(blend); +} + +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); +} + +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); + /*XXX: clear NV04_NEW_FRAGPROG if no new program uploaded */ + 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_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); + } + + /* 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 */ +/* BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(rt->stride|(zeta->stride<<16)); + OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (fb->zsbuf) { + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RELOCl(zeta->buffer, 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*/); + } +} + |