sp_fs_exec.c revision e8de5c70e3370e9112a5facc870075eea60c4c46
1/**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include "sp_context.h"
30#include "sp_state.h"
31#include "sp_fs.h"
32#include "sp_headers.h"
33
34
35#include "pipe/p_state.h"
36#include "pipe/p_defines.h"
37#include "pipe/p_util.h"
38#include "pipe/p_inlines.h"
39#include "tgsi/exec/tgsi_exec.h"
40
41struct sp_exec_fragment_shader {
42   struct sp_fragment_shader base;
43};
44
45
46
47/**
48 * Compute quad X,Y,Z,W for the four fragments in a quad.
49 *
50 * This should really be part of the compiled shader.
51 */
52void
53sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
54		    float x, float y,
55		    struct tgsi_exec_vector *quadpos)
56{
57   uint chan;
58   /* do X */
59   quadpos->xyzw[0].f[0] = x;
60   quadpos->xyzw[0].f[1] = x + 1;
61   quadpos->xyzw[0].f[2] = x;
62   quadpos->xyzw[0].f[3] = x + 1;
63
64   /* do Y */
65   quadpos->xyzw[1].f[0] = y;
66   quadpos->xyzw[1].f[1] = y;
67   quadpos->xyzw[1].f[2] = y + 1;
68   quadpos->xyzw[1].f[3] = y + 1;
69
70   /* do Z and W for all fragments in the quad */
71   for (chan = 2; chan < 4; chan++) {
72      const float dadx = coef->dadx[chan];
73      const float dady = coef->dady[chan];
74      const float a0 = coef->a0[chan] + dadx * x + dady * y;
75      quadpos->xyzw[chan].f[0] = a0;
76      quadpos->xyzw[chan].f[1] = a0 + dadx;
77      quadpos->xyzw[chan].f[2] = a0 + dady;
78      quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
79   }
80}
81
82
83static void
84exec_prepare( const struct sp_fragment_shader *base,
85	      struct tgsi_exec_machine *machine,
86	      struct tgsi_sampler *samplers )
87{
88   tgsi_exec_machine_bind_shader( machine,
89				  base->shader.tokens,
90				  PIPE_MAX_SAMPLERS,
91				  samplers );
92}
93
94
95
96
97/* TODO: hide the machine struct in here somewhere, remove from this
98 * interface:
99 */
100static unsigned
101exec_run( const struct sp_fragment_shader *base,
102	  struct tgsi_exec_machine *machine,
103	  struct quad_header *quad )
104{
105
106   /* Compute X, Y, Z, W vals for this quad */
107   sp_setup_pos_vector(quad->posCoef,
108		       (float)quad->x0, (float)quad->y0,
109		       &machine->QuadPos);
110
111   return tgsi_exec_machine_run( machine );
112}
113
114
115
116static void
117exec_delete( struct sp_fragment_shader *base )
118{
119   FREE(base);
120}
121
122
123
124
125
126struct sp_fragment_shader *
127softpipe_create_fs_exec(struct softpipe_context *softpipe,
128			const struct pipe_shader_state *templ)
129{
130   struct sp_exec_fragment_shader *shader;
131
132   /* Decide whether we'll be codegenerating this shader and if so do
133    * that now.
134    */
135
136   shader = CALLOC_STRUCT(sp_exec_fragment_shader);
137   if (!shader)
138      return NULL;
139
140   shader->base.shader = *templ;
141   shader->base.prepare = exec_prepare;
142   shader->base.run = exec_run;
143   shader->base.delete = exec_delete;
144
145   return &shader->base;
146}
147
148