sp_fs_exec.c revision e6e58cfa9dd8cbd5d6977822355d150e76eb987a
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    * Avoid redundant binding.
70da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell    */
71c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   if (machine->Tokens != var->tokens) {
72da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell      tgsi_exec_machine_bind_shader( machine,
73c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                                     var->tokens,
74da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                                     PIPE_MAX_SAMPLERS,
75da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                                     samplers );
76da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell   }
77da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell}
78da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell
79da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell
80da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell
8120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell/**
8220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell * Compute quad X,Y,Z,W for the four fragments in a quad.
8320fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell *
8420fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell * This should really be part of the compiled shader.
8520fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell */
86da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellstatic void
87da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellsetup_pos_vector(const struct tgsi_interp_coef *coef,
88da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                 float x, float y,
89da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                 struct tgsi_exec_vector *quadpos)
9020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell{
9120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   uint chan;
9220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   /* do X */
9320fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[0] = x;
9420fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[1] = x + 1;
9520fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[2] = x;
9620fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[0].f[3] = x + 1;
9720fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell
9820fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   /* do Y */
9920fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[0] = y;
10020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[1] = y;
10120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[2] = y + 1;
10220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   quadpos->xyzw[1].f[3] = y + 1;
10320fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell
10420fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   /* do Z and W for all fragments in the quad */
10520fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   for (chan = 2; chan < 4; chan++) {
10620fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      const float dadx = coef->dadx[chan];
10720fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      const float dady = coef->dady[chan];
10820fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      const float a0 = coef->a0[chan] + dadx * x + dady * y;
10920fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[0] = a0;
11020fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[1] = a0 + dadx;
11120fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[2] = a0 + dady;
11220fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell      quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
11320fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell   }
11420fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell}
11520fbcbf5801c28865c0bfab3cda45302c8474a66Keith Whitwell
116c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
117c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell/* TODO: hide the machine struct in here somewhere, remove from this
118c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell * interface:
119c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell */
120c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellstatic unsigned
121c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulexec_run( const struct sp_fragment_shader_variant *var,
122c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell	  struct tgsi_exec_machine *machine,
123c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell	  struct quad_header *quad )
124c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
125c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   /* Compute X, Y, Z, W vals for this quad */
126da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell   setup_pos_vector(quad->posCoef,
127da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                    (float)quad->input.x0, (float)quad->input.y0,
128da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                    &machine->QuadPos);
129cc93fa3527e64963acd0e643d7d1061306d9e1dfMichal Krol
130e0399fddf2efd556ece8b81078368e6ab388c3b7Brian Paul   /* convert 0 to 1.0 and 1 to -1.0 */
131e0399fddf2efd556ece8b81078368e6ab388c3b7Brian Paul   machine->Face = (float) (quad->input.facing * -2 + 1);
132cc93fa3527e64963acd0e643d7d1061306d9e1dfMichal Krol
13395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   quad->inout.mask &= tgsi_exec_machine_run( machine );
13495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   if (quad->inout.mask == 0)
13595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      return FALSE;
13695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell
13795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   /* store outputs */
13895f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   {
139c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      const ubyte *sem_name = var->info.output_semantic_name;
140c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      const ubyte *sem_index = var->info.output_semantic_index;
141c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      const uint n = var->info.num_outputs;
14295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      uint i;
14395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      for (i = 0; i < n; i++) {
14495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         switch (sem_name[i]) {
14595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         case TGSI_SEMANTIC_COLOR:
14695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            {
14795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               uint cbuf = sem_index[i];
1487069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul
1497069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul               assert(sizeof(quad->output.color[cbuf]) ==
1507069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul                      sizeof(machine->Outputs[i]));
1517069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul
1527069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul               /* copy float[4][4] result */
15395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               memcpy(quad->output.color[cbuf],
1547069dff80f25d0ac532c9f76634d1cd382d4fac1Brian Paul                      &machine->Outputs[i],
15595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell                      sizeof(quad->output.color[0]) );
15695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            }
15795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            break;
15895f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         case TGSI_SEMANTIC_POSITION:
15995f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            {
16095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               uint j;
1614ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie
1624ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie               for (j = 0; j < 4; j++)
16369c7fc128c59bf72df461dbd583bf9794d9ed34dMichal Krol                  quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j];
1644ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie            }
1654ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie            break;
1664ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie         case TGSI_SEMANTIC_STENCIL:
1674ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie            {
1684ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie               uint j;
1694ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie
1704ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie               for (j = 0; j < 4; j++)
1714ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                  quad->output.stencil[j] = (unsigned)machine->Outputs[i].xyzw[1].f[j];
17295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            }
17395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            break;
17495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         }
17595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      }
17695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   }
17795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell
17895f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   return TRUE;
179c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
180c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
181c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
182c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellstatic void
183e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paulexec_delete(struct sp_fragment_shader_variant *var,
184e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul            struct tgsi_exec_machine *machine)
185c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
186e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul   if (machine->Tokens == var->tokens) {
187e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul      tgsi_exec_machine_bind_shader(machine, NULL, 0, NULL);
188e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul   }
189e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul
190c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   FREE( (void *) var->tokens );
191c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   FREE(var);
192c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
193c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
194c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
195c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulstruct sp_fragment_shader_variant *
196c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulsoftpipe_create_fs_variant_exec(struct softpipe_context *softpipe,
197c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                                const struct pipe_shader_state *templ)
198c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
199c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   struct sp_exec_fragment_shader *shader;
200c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
201c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader = CALLOC_STRUCT(sp_exec_fragment_shader);
202c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   if (!shader)
203c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell      return NULL;
204c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
205c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.prepare = exec_prepare;
206c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.run = exec_run;
207c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.delete = exec_delete;
208c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
209c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   return &shader->base;
210c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
211