sp_fs_exec.c revision da319095f2ca8869657ebda0db54eb9b2f7393ce
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/**
45bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul * Subclass of sp_fragment_shader
46bab6d6bfe928687717a5e5f274110fe1838f99baBrian Paul */
4705aeb92a092c26e7773beb95692fc72e70a40e56Brian Paulstruct sp_exec_fragment_shader
4805aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul{
49c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   struct sp_fragment_shader 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 *
565f88d871ea051e0c89bbbfc832a565fc8de70c6aJosé Fonsecasp_exec_fragment_shader(const struct sp_fragment_shader *base)
5705aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul{
5805aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul   return (struct sp_exec_fragment_shader *) base;
5905aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul}
6005aeb92a092c26e7773beb95692fc72e70a40e56Brian Paul
61c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
62da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellstatic void
63da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwellexec_prepare( const struct sp_fragment_shader *base,
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    */
71da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell   if (machine->Tokens != base->shader.tokens) {
72da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell      tgsi_exec_machine_bind_shader( machine,
73da319095f2ca8869657ebda0db54eb9b2f7393ceKeith Whitwell                                     base->shader.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
121e8de5c70e3370e9112a5facc870075eea60c4c46José Fonsecaexec_run( const struct sp_fragment_shader *base,
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);
129c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
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   {
13695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      const ubyte *sem_name = base->info.output_semantic_name;
13795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      const ubyte *sem_index = base->info.output_semantic_index;
13895f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      const uint n = base->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];
14595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               memcpy(quad->output.color[cbuf],
14695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell                      &machine->Outputs[i].xyzw[0].f[0],
14795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell                      sizeof(quad->output.color[0]) );
14895f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            }
14995f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            break;
15095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         case TGSI_SEMANTIC_POSITION:
15195f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            {
15295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               uint j;
15395f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               for (j = 0; j < 4; j++) {
15495f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell                  quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j];
15595f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell               }
15695f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            }
15795f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell            break;
15895f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell         }
15995f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell      }
16095f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   }
16195f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell
16295f7ed4638d4e379783abdd5b250e203b6b1b435Keith Whitwell   return TRUE;
163c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
164c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
165c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
166c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellstatic void
167c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellexec_delete( struct sp_fragment_shader *base )
168c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
1699671f7ae476cadb46f9f8f9d0363f24aabaf9f87Brian Paul   FREE((void *) base->shader.tokens);
170c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   FREE(base);
171c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
172c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
173c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
174c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellstruct sp_fragment_shader *
175c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwellsoftpipe_create_fs_exec(struct softpipe_context *softpipe,
176c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell			const struct pipe_shader_state *templ)
177c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell{
178c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   struct sp_exec_fragment_shader *shader;
179c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
180c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   /* Decide whether we'll be codegenerating this shader and if so do
181c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell    * that now.
182c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell    */
183c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
184c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader = CALLOC_STRUCT(sp_exec_fragment_shader);
185c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   if (!shader)
186c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell      return NULL;
187c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
1889671f7ae476cadb46f9f8f9d0363f24aabaf9f87Brian Paul   /* we need to keep a local copy of the tokens */
1899671f7ae476cadb46f9f8f9d0363f24aabaf9f87Brian Paul   shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens);
190c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.prepare = exec_prepare;
191c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.run = exec_run;
192c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   shader->base.delete = exec_delete;
193c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell
194c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   return &shader->base;
195c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell}
196