From 73af91e938eb27b001404f11195fb06ff9b08903 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 14 Aug 2009 10:27:32 +0100 Subject: llvmpipe: Eliminate non-LLVM fs execution paths. --- src/gallium/drivers/llvmpipe/lp_quad_fs.c | 119 ++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_quad_fs.c') diff --git a/src/gallium/drivers/llvmpipe/lp_quad_fs.c b/src/gallium/drivers/llvmpipe/lp_quad_fs.c index 1da50e493b..338a6be80c 100644 --- a/src/gallium/drivers/llvmpipe/lp_quad_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_quad_fs.c @@ -1,8 +1,8 @@ /************************************************************************** * + * Copyright 2008-2009 VMware, Inc. * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * Copyright 2008 VMware, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -65,6 +65,114 @@ quad_shade_stage(struct quad_stage *qs) } +static void +shader_prepare( const struct lp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler **samplers ) +{ + /* + * Bind tokens/shader to the interpreter's machine state. + * Avoid redundant binding. + */ + if (machine->Tokens != shader->base.tokens) { + tgsi_exec_machine_bind_shader( machine, + shader->base.tokens, + PIPE_MAX_SAMPLERS, + samplers ); + } +} + + + +static void +setup_pos_vector(struct lp_fragment_shader *shader, + const struct tgsi_interp_coef *coef, + float x, float y) +{ + uint chan; + + /* do X */ + shader->pos[0].f[0] = x; + shader->pos[0].f[1] = x + 1; + shader->pos[0].f[2] = x; + shader->pos[0].f[3] = x + 1; + + /* do Y */ + shader->pos[1].f[0] = y; + shader->pos[1].f[1] = y; + shader->pos[1].f[2] = y + 1; + shader->pos[1].f[3] = y + 1; + + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + shader->pos[chan].f[0] = a0; + shader->pos[chan].f[1] = a0 + dadx; + shader->pos[chan].f[2] = a0 + dady; + shader->pos[chan].f[3] = a0 + dadx + dady; + } +} + + +static void +setup_coef_vector(struct lp_fragment_shader *shader, + const struct tgsi_interp_coef *coef) +{ + unsigned attrib, chan, i; + + for (attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; ++attrib) { + for (chan = 0; chan < NUM_CHANNELS; ++chan) { + for( i = 0; i < QUAD_SIZE; ++i ) { + shader->a0[attrib][chan].f[i] = coef[attrib].a0[chan]; + shader->dadx[attrib][chan].f[i] = coef[attrib].dadx[chan]; + shader->dady[attrib][chan].f[i] = coef[attrib].dady[chan]; + } + } + } +} + + +/* TODO: codegenerate the whole run function, skip this wrapper. + * TODO: break dependency on tgsi_exec_machine struct + * TODO: push Position calculation into the generated shader + * TODO: process >1 quad at a time + */ +static unsigned +shader_run( struct lp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) +{ + unsigned mask; + + /* Compute X, Y, Z, W vals for this quad */ + setup_pos_vector(shader, + quad->posCoef, + (float)quad->input.x0, (float)quad->input.y0); + + setup_coef_vector(shader, + quad->coef); + + /* init kill mask */ + tgsi_set_kill_mask(machine, 0x0); + tgsi_set_exec_mask(machine, 1, 1, 1, 1); + + memset(machine->Outputs, 0, sizeof machine->Outputs); + + shader->jit_function( shader->pos, + shader->a0, shader->dadx, shader->dady, + machine->Consts, + machine->Outputs, + machine->Samplers); + + /* FIXME */ + mask = ~0; + + return mask; +} + + /** * Execute fragment shader for the four fragments in the quad. */ @@ -77,7 +185,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) boolean z_written; /* run shader */ - quad->inout.mask &= llvmpipe->fs->run( llvmpipe->fs, machine, quad ); + quad->inout.mask &= shader_run( llvmpipe->fs, machine, quad ); if (quad->inout.mask == 0) return FALSE; @@ -177,10 +285,9 @@ shade_begin(struct quad_stage *qs) struct quad_shade_stage *qss = quad_shade_stage(qs); struct llvmpipe_context *llvmpipe = qs->llvmpipe; - llvmpipe->fs->prepare( llvmpipe->fs, - qss->machine, - (struct tgsi_sampler **) - llvmpipe->tgsi.frag_samplers_list ); + shader_prepare( llvmpipe->fs, + qss->machine, + (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list ); qs->next->begin(qs->next); } -- cgit v1.2.3