#include "pipe/p_state.h"
#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "pipe/p_inlines.h"
-#include "tgsi/exec/tgsi_exec.h"
+#include "tgsi/tgsi_exec.h"
+#include "tgsi/tgsi_parse.h"
-struct sp_exec_fragment_shader {
+struct sp_exec_fragment_shader
+{
struct sp_fragment_shader base;
};
+/** cast wrapper */
+static INLINE struct sp_exec_fragment_shader *
+sp_exec_fragment_shader(const struct sp_fragment_shader *base)
+{
+ return (struct sp_exec_fragment_shader *) base;
+}
+
+
+/**
+ * Compute quad X,Y,Z,W for the four fragments in a quad.
+ *
+ * This should really be part of the compiled shader.
+ */
+void
+sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
+ float x, float y,
+ struct tgsi_exec_vector *quadpos)
+{
+ uint chan;
+ /* do X */
+ quadpos->xyzw[0].f[0] = x;
+ quadpos->xyzw[0].f[1] = x + 1;
+ quadpos->xyzw[0].f[2] = x;
+ quadpos->xyzw[0].f[3] = x + 1;
+
+ /* do Y */
+ quadpos->xyzw[1].f[0] = y;
+ quadpos->xyzw[1].f[1] = y;
+ quadpos->xyzw[1].f[2] = y + 1;
+ quadpos->xyzw[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;
+ quadpos->xyzw[chan].f[0] = a0;
+ quadpos->xyzw[chan].f[1] = a0 + dadx;
+ quadpos->xyzw[chan].f[2] = a0 + dady;
+ quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
+ }
+}
static void
-exec_prepare( struct sp_fragment_shader *base,
+exec_prepare( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
- struct tgsi_sampler *samplers )
+ struct tgsi_sampler **samplers )
{
- tgsi_exec_machine_bind_shader( machine,
- base->shader.tokens,
- PIPE_MAX_SAMPLERS,
- samplers );
+ /*
+ * Bind tokens/shader to the interpreter's machine state.
+ * Avoid redundant binding.
+ */
+ if (machine->Tokens != base->shader.tokens) {
+ tgsi_exec_machine_bind_shader( machine,
+ base->shader.tokens,
+ PIPE_MAX_SAMPLERS,
+ samplers );
+ }
}
* interface:
*/
static unsigned
-exec_run( struct sp_fragment_shader *base,
+exec_run( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
struct quad_header *quad )
{
/* Compute X, Y, Z, W vals for this quad */
sp_setup_pos_vector(quad->posCoef,
- (float)quad->x0, (float)quad->y0,
+ (float)quad->input.x0, (float)quad->input.y0,
&machine->QuadPos);
return tgsi_exec_machine_run( machine );
static void
exec_delete( struct sp_fragment_shader *base )
{
+ FREE((void *) base->shader.tokens);
FREE(base);
}
if (!shader)
return NULL;
- shader->base.shader = *templ;
+ /* we need to keep a local copy of the tokens */
+ shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens);
shader->base.prepare = exec_prepare;
shader->base.run = exec_run;
shader->base.delete = exec_delete;