1c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell/**************************************************************************
2c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell *
3c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * All Rights Reserved.
5c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell *
6c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
7c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * copy of this software and associated documentation files (the
8c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * "Software"), to deal in the Software without restriction, including
9c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
10c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
11c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * permit persons to whom the Software is furnished to do so, subject to
12c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * the following conditions:
13c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell *
14c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * The above copyright notice and this permission notice (including the
15c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * next paragraph) shall be included in all copies or substantial portions
16c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * of the Software.
17c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell *
18c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell *
26c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell **************************************************************************/
27c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
28bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul/**
29bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul * Execute fragment shader using the TGSI interpreter.
30bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul */
31c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
32c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "sp_context.h"
33c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "sp_state.h"
34c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "sp_fs.h"
357925274da323d5a896b557181d4016e0391f026fBrian#include "sp_quad.h"
36c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
37c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "pipe/p_state.h"
38c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "pipe/p_defines.h"
394f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
40c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_exec.h"
41c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_parse.h"
42c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
43bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul
44bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul/**
45c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul * Subclass of sp_fragment_shader_variant
46bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul */
4705aeb92a092c26e7773beb95692fc72e70a40e56Brian Paulstruct sp_exec_fragment_shader
4805aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul{
49c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   struct sp_fragment_shader_variant base;
50bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul   /* No other members for now */
51c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell};
52c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
53c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
5405aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul/** cast wrapper */
5505aeb92a092c26e7773beb95692fc72e70a40e56Brian Paulstatic INLINE struct sp_exec_fragment_shader *
56c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulsp_exec_fragment_shader(const struct sp_fragment_shader_variant *var)
5705aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul{
58c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   return (struct sp_exec_fragment_shader *) var;
5905aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul}
6005aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul
61c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
62da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellstatic void
63c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulexec_prepare( const struct sp_fragment_shader_variant *var,
64da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell	      struct tgsi_exec_machine *machine,
65da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell	      struct tgsi_sampler **samplers )
66da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell{
67da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell   /*
68da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell    * Bind tokens/shader to the interpreter's machine state.
69da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell    */
70e8830f5a4009c3784836edb441319a62c7beef36Brian Paul   tgsi_exec_machine_bind_shader(machine,
71e8830f5a4009c3784836edb441319a62c7beef36Brian Paul                                 var->tokens,
72e8830f5a4009c3784836edb441319a62c7beef36Brian Paul                                 PIPE_MAX_SAMPLERS,
73e8830f5a4009c3784836edb441319a62c7beef36Brian Paul                                 samplers);
74da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell}
75da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell
76da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell
77da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell
7820fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell/**
7920fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell * Compute quad X,Y,Z,W for the four fragments in a quad.
8020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell *
8120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell * This should really be part of the compiled shader.
8220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell */
83da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellstatic void
84da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellsetup_pos_vector(const struct tgsi_interp_coef *coef,
85da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                 float x, float y,
86da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                 struct tgsi_exec_vector *quadpos)
8720fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell{
8820fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   uint chan;
8920fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   /* do X */
9020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[0] = x;
9120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[1] = x + 1;
9220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[2] = x;
9320fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[3] = x + 1;
9420fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell
9520fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   /* do Y */
9620fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[0] = y;
9720fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[1] = y;
9820fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[2] = y + 1;
9920fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[3] = y + 1;
10020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell
10120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   /* do Z and W for all fragments in the quad */
10220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   for (chan = 2; chan < 4; chan++) {
10320fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      const float dadx = coef->dadx[chan];
10420fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      const float dady = coef->dady[chan];
10520fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      const float a0 = coef->a0[chan] + dadx * x + dady * y;
10620fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[0] = a0;
10720fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[1] = a0 + dadx;
10820fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[2] = a0 + dady;
10920fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
11020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   }
11120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell}
11220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell
113c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
114c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell/* TODO: hide the machine struct in here somewhere, remove from this
115c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * interface:
116c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell */
117c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellstatic unsigned
118c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulexec_run( const struct sp_fragment_shader_variant *var,
119c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell	  struct tgsi_exec_machine *machine,
120c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell	  struct quad_header *quad )
121c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
122c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   /* Compute X, Y, Z, W vals for this quad */
123da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell   setup_pos_vector(quad->posCoef,
124da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                    (float)quad->input.x0, (float)quad->input.y0,
125da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                    &machine->QuadPos);
126cc93fa3527e64963acd0e643d7d1061306d9e1dfMichal Krol
127e0399fddf2efd556ece8b81078368e6ab388c3b7Brian Paul   /* convert 0 to 1.0 and 1 to -1.0 */
128e0399fddf2efd556ece8b81078368e6ab388c3b7Brian Paul   machine->Face = (float) (quad->input.facing * -2 + 1);
129cc93fa3527e64963acd0e643d7d1061306d9e1dfMichal Krol
13095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   quad->inout.mask &= tgsi_exec_machine_run( machine );
13195f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   if (quad->inout.mask == 0)
13295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      return FALSE;
13395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell
13495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   /* store outputs */
13595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   {
136c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      const ubyte *sem_name = var->info.output_semantic_name;
137c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      const ubyte *sem_index = var->info.output_semantic_index;
138c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      const uint n = var->info.num_outputs;
13995f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      uint i;
14095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      for (i = 0; i < n; i++) {
14195f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         switch (sem_name[i]) {
14295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         case TGSI_SEMANTIC_COLOR:
14395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            {
14495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               uint cbuf = sem_index[i];
1457069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul
1467069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul               assert(sizeof(quad->output.color[cbuf]) ==
1477069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul                      sizeof(machine->Outputs[i]));
1487069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul
1497069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul               /* copy float[4][4] result */
15095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               memcpy(quad->output.color[cbuf],
1517069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul                      &machine->Outputs[i],
15295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell                      sizeof(quad->output.color[0]) );
15395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            }
15495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            break;
15595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         case TGSI_SEMANTIC_POSITION:
15695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            {
15795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               uint j;
1584ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie
1594ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie               for (j = 0; j < 4; j++)
16069c7fc128c59bf72df461dbd583bf9794d9ed34dMichal Krol                  quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j];
1614ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie            }
1624ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie            break;
1634ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie         case TGSI_SEMANTIC_STENCIL:
1644ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie            {
1654ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie               uint j;
1664ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie
1674ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie               for (j = 0; j < 4; j++)
1684ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                  quad->output.stencil[j] = (unsigned)machine->Outputs[i].xyzw[1].f[j];
16995f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            }
17095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            break;
17195f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         }
17295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      }
17395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   }
17495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell
17595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   return TRUE;
176c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
177c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
178c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
179c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellstatic void
180e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paulexec_delete(struct sp_fragment_shader_variant *var,
181e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul            struct tgsi_exec_machine *machine)
182c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
183e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul   if (machine->Tokens == var->tokens) {
184e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul      tgsi_exec_machine_bind_shader(machine, NULL, 0, NULL);
185e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul   }
186e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul
187c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   FREE( (void *) var->tokens );
188c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   FREE(var);
189c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
190c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
191c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
192c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulstruct sp_fragment_shader_variant *
193c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulsoftpipe_create_fs_variant_exec(struct softpipe_context *softpipe,
194c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                                const struct pipe_shader_state *templ)
195c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
196c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   struct sp_exec_fragment_shader *shader;
197c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
198c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader = CALLOC_STRUCT(sp_exec_fragment_shader);
199c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   if (!shader)
200c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell      return NULL;
201c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
202c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.prepare = exec_prepare;
203c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.run = exec_run;
204c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.delete = exec_delete;
205c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
206c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   return &shader->base;
207c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
208