18e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/**************************************************************************
28e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
3c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
48e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * All Rights Reserved.
58e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
68e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
78e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * copy of this software and associated documentation files (the
88e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * "Software"), to deal in the Software without restriction, including
98e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * the following conditions:
138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * The above copyright notice and this permission notice (including the
158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * of the Software.
178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
208e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
248e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
268e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell **************************************************************************/
278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
286393cda6766b707ef01e925d378239a66d143ae0Keith Whitwell#include "sp_context.h"
296393cda6766b707ef01e925d378239a66d143ae0Keith Whitwell#include "sp_state.h"
30c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "sp_fs.h"
31287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "sp_texture.h"
328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
33c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian#include "pipe/p_defines.h"
344f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
3528486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
3657aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul#include "util/u_pstipple.h"
376ac2c1cc0cd1253ba2014d459010032127f185ecKeith Whitwell#include "draw/draw_context.h"
384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell#include "draw/draw_vs.h"
3953bd9796a1395e4acde884ff55cb7ee18586595aZack Rusin#include "draw/draw_gs.h"
40c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_dump.h"
41c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_scan.h"
42fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell#include "tgsi/tgsi_parse.h"
438e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
45c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul/**
46c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul * Create a new fragment shader variant.
47c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul */
48c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulstatic struct sp_fragment_shader_variant *
49c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulcreate_fs_variant(struct softpipe_context *softpipe,
50c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                  struct sp_fragment_shader *fs,
51c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                  const struct sp_fragment_shader_variant_key *key)
52c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul{
53c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   struct sp_fragment_shader_variant *var;
5457aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul   struct pipe_shader_state *stipple_fs = NULL, *curfs = &fs->shader;
5557aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul   unsigned unit = 0;
5657aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul
57334a9dd3e60e9c7b8ba7bcceb2c88c2645e6220bBrian Paul#if DO_PSTIPPLE_IN_HELPER_MODULE
5857aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul   if (key->polygon_stipple) {
5957aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul      /* get new shader that implements polygon stippling */
6057aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul      stipple_fs = util_pstipple_create_fragment_shader(&softpipe->pipe,
6157aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul                                                        curfs, &unit);
6257aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul      curfs = stipple_fs;
6357aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul   }
64334a9dd3e60e9c7b8ba7bcceb2c88c2645e6220bBrian Paul#endif
65c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
66c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   /* codegen, create variant object */
674eb3225b38ce12cb34ab3d90804c9683bd7b4ed3José Fonseca   var = softpipe_create_fs_variant_exec(softpipe, curfs);
68c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
69c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   if (var) {
70c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      var->key = *key;
71c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      var->tokens = tgsi_dup_tokens(curfs->tokens);
7257aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul      var->stipple_sampler_unit = unit;
73c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
74c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      tgsi_scan_shader(var->tokens, &var->info);
75c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
76c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      /* See comments elsewhere about draw fragment shaders */
77c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#if 0
78c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      /* draw's fs state */
79c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      var->draw_shader = draw_create_fragment_shader(softpipe->draw,
80c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                                                     &fs->shader);
81c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      if (!var->draw_shader) {
82c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul         var->delete(var);
83c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul         FREE((void *) var->tokens);
84c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul         return NULL;
85c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      }
86c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#endif
87c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
88c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      /* insert variant into linked list */
89c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      var->next = fs->variants;
90c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      fs->variants = var;
91c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   }
92c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
9357aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul   if (stipple_fs) {
94f32c9c210875b2ce4878f97b84bdd4739bd489f9José Fonseca      FREE((void *) stipple_fs->tokens);
95f32c9c210875b2ce4878f97b84bdd4739bd489f9José Fonseca      FREE(stipple_fs);
9657aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul   }
9757aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul
98c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   return var;
99c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul}
100c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
101c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
102c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulstruct sp_fragment_shader_variant *
103c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulsoftpipe_find_fs_variant(struct softpipe_context *sp,
104c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                         struct sp_fragment_shader *fs,
105c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                         const struct sp_fragment_shader_variant_key *key)
106c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul{
107c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   struct sp_fragment_shader_variant *var;
108c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
109c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   for (var = fs->variants; var; var = var->next) {
110c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      if (memcmp(&var->key, key, sizeof(*key)) == 0) {
111c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul         /* found it */
112c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul         return var;
113c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      }
114c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   }
115c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
116c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   return create_fs_variant(sp, fs, key);
117c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul}
118c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
119c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
120279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void *
1212b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_create_fs_state(struct pipe_context *pipe,
1222b40838972bb84a0dff8f8a3c933b0d2b8384f10Brian                         const struct pipe_shader_state *templ)
123ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin{
124344464bf2e4e151968cfb101c2477e440508b1f0Michel Dänzer   struct softpipe_context *softpipe = softpipe_context(pipe);
125c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   struct sp_fragment_shader *state = CALLOC_STRUCT(sp_fragment_shader);
126344464bf2e4e151968cfb101c2477e440508b1f0Michel Dänzer
127f74279002a0ae0b106bd5410487ef9c0e9b1d8b6Brian   /* debug */
128c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   if (softpipe->dump_fs)
129c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell      tgsi_dump(templ->tokens, 0);
13052659e3c238d961de1f25bed9254747f2f931547Brian
131c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   /* we need to keep a local copy of the tokens */
132c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
133e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul
134e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   /* draw's fs state */
135c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   state->draw_shader = draw_create_fragment_shader(softpipe->draw,
136c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                                                    &state->shader);
137e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   if (!state->draw_shader) {
138c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      FREE((void *) state->shader.tokens);
139c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      FREE(state);
140e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul      return NULL;
141e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   }
142f74279002a0ae0b106bd5410487ef9c0e9b1d8b6Brian
14351345cb3c4d85a9e88ac35b59e938b0692df6205Zack Rusin   return state;
144ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin}
145ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin
14652659e3c238d961de1f25bed9254747f2f931547Brian
147279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
1482b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
1498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
1506393cda6766b707ef01e925d378239a66d143ae0Keith Whitwell   struct softpipe_context *softpipe = softpipe_context(pipe);
151c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   struct sp_fragment_shader *state = (struct sp_fragment_shader *) fs;
1528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1534ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca   if (softpipe->fs == fs)
1544ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca      return;
1554ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca
1564ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca   draw_flush(softpipe->draw);
1574ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca
1584ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca   softpipe->fs = fs;
1598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
16016c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul   /* This depends on the current fragment shader and must always be
16116c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul    * re-validated before use.
16216c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul    */
16316c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul   softpipe->fs_variant = NULL;
164c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
165c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   if (state)
166c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      draw_bind_fragment_shader(softpipe->draw,
167c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul                                state->draw_shader);
168c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   else
169c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      draw_bind_fragment_shader(softpipe->draw, NULL);
170e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul
171a380f98b6cc1da78d0845746ab86c3490a800126Brian   softpipe->dirty |= SP_NEW_FS;
1728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
1738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
17452659e3c238d961de1f25bed9254747f2f931547Brian
175279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
1762b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
177a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin{
1781fce9d58cc70deaff284e1d9d0ffcb15b61e7595Brian Paul   struct softpipe_context *softpipe = softpipe_context(pipe);
179c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   struct sp_fragment_shader *state = fs;
180c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   struct sp_fragment_shader_variant *var, *next_var;
181ce454d2192918ae4b2535d0e76c68ebde3c4653fBrian Paul
182c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   assert(fs != softpipe->fs);
1831fce9d58cc70deaff284e1d9d0ffcb15b61e7595Brian Paul
184c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   /* delete variants */
185c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   for (var = state->variants; var; var = next_var) {
186c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      next_var = var->next;
187c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
188c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      assert(var != softpipe->fs_variant);
189c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
190c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      /* See comments elsewhere about draw fragment shaders */
191c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#if 0
192c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul      draw_delete_fragment_shader(softpipe->draw, var->draw_shader);
193c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#endif
194c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
195e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul      var->delete(var, softpipe->fs_machine);
196c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   }
197c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul
198e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
199e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul
200c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul   FREE((void *) state->shader.tokens);
20189d6044b7b70304bdd9ebab734d8b1c0826cbdb8Morgan Armand   FREE(state);
202a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin}
203a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin
204a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin
205279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void *
2062b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_create_vs_state(struct pipe_context *pipe,
2072b40838972bb84a0dff8f8a3c933b0d2b8384f10Brian                         const struct pipe_shader_state *templ)
208a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin{
209a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin   struct softpipe_context *softpipe = softpipe_context(pipe);
210c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   struct sp_vertex_shader *state;
211ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol
212c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell   state = CALLOC_STRUCT(sp_vertex_shader);
213fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   if (state == NULL )
214fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell      goto fail;
215fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell
216fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   /* copy shader tokens, the ones passed in will go away.
217fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell    */
218fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
219fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   if (state->shader.tokens == NULL)
220fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell      goto fail;
221ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol
2229671f7ae476cadb46f9f8f9d0363f24aabaf9f87Brian Paul   state->draw_data = draw_create_vertex_shader(softpipe->draw, templ);
223fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   if (state->draw_data == NULL)
224fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell      goto fail;
225a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin
2264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
2274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
228a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin   return state;
229fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell
230fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwellfail:
231fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   if (state) {
232fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell      FREE( (void *)state->shader.tokens );
233fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell      FREE( state->draw_data );
234fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell      FREE( state );
235fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   }
236fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell   return NULL;
237a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin}
2388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
23952659e3c238d961de1f25bed9254747f2f931547Brian
240279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
2412b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
242de653b4c9bddcec46f3ddf411ec082dd178d7b38Brian{
243de653b4c9bddcec46f3ddf411ec082dd178d7b38Brian   struct softpipe_context *softpipe = softpipe_context(pipe);
2448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2454256c5829f8c23f8bd5c7c29491210f0f7813bf9Brian Paul   softpipe->vs = (struct sp_vertex_shader *) vs;
2460a262998ef2813d19e9fee01d3e5808416e9cb04Brian
247339e7ec6805e6de8794514c0a935081b5d36d38fBrian   draw_bind_vertex_shader(softpipe->draw,
248339e7ec6805e6de8794514c0a935081b5d36d38fBrian                           (softpipe->vs ? softpipe->vs->draw_data : NULL));
249c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian
250a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin   softpipe->dirty |= SP_NEW_VS;
251ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin}
252ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin
25352659e3c238d961de1f25bed9254747f2f931547Brian
254279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
2552b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
256901577e07fcab0cf90a272fee900cb0831ae84c3Zack Rusin{
257a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin   struct softpipe_context *softpipe = softpipe_context(pipe);
258a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin
2594256c5829f8c23f8bd5c7c29491210f0f7813bf9Brian Paul   struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
260a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin
261a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin   draw_delete_vertex_shader(softpipe->draw, state->draw_data);
262a24631bcd7ab2cbc6fff2a536502a07a13a9bc83Alan Hourihane   FREE( (void *)state->shader.tokens );
263ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol   FREE( state );
264901577e07fcab0cf90a272fee900cb0831ae84c3Zack Rusin}
2656dcfddb8e2ec2bfb6187b912807fa65f28da2c5eZack Rusin
2664ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca
267279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void *
26889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinsoftpipe_create_gs_state(struct pipe_context *pipe,
26989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         const struct pipe_shader_state *templ)
27089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
27189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct softpipe_context *softpipe = softpipe_context(pipe);
27289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct sp_geometry_shader *state;
27389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
27489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   state = CALLOC_STRUCT(sp_geometry_shader);
27589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (state == NULL )
27689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      goto fail;
27789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
278ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin   /* debug */
279ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin   if (softpipe->dump_gs)
280ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin      tgsi_dump(templ->tokens, 0);
281ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin
28289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   /* copy shader tokens, the ones passed in will go away.
28389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin    */
28489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
28589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (state->shader.tokens == NULL)
28689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      goto fail;
28789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
28889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
28989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (state->draw_data == NULL)
29089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      goto fail;
29189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
29253bd9796a1395e4acde884ff55cb7ee18586595aZack Rusin   state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
29353bd9796a1395e4acde884ff55cb7ee18586595aZack Rusin
29489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   return state;
29589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
29689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinfail:
29789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (state) {
29889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      FREE( (void *)state->shader.tokens );
29989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      FREE( state->draw_data );
30089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      FREE( state );
30189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
30289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   return NULL;
30389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
30489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
30589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
306279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
30789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinsoftpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
30889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
30989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct softpipe_context *softpipe = softpipe_context(pipe);
31089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
31189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   softpipe->gs = (struct sp_geometry_shader *)gs;
31289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
31389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   draw_bind_geometry_shader(softpipe->draw,
31489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                             (softpipe->gs ? softpipe->gs->draw_data : NULL));
31589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
31689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   softpipe->dirty |= SP_NEW_GS;
31789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
31889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
31989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
320279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
32189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinsoftpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
32289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
32389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct softpipe_context *softpipe = softpipe_context(pipe);
32489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
32589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct sp_geometry_shader *state =
32689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      (struct sp_geometry_shader *)gs;
32789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
32842eefb8235437655632b36490f49a3a8fdc69401Zack Rusin   draw_delete_geometry_shader(softpipe->draw,
32942eefb8235437655632b36490f49a3a8fdc69401Zack Rusin                               (state) ? state->draw_data : 0);
33089d6044b7b70304bdd9ebab734d8b1c0826cbdb8Morgan Armand
33189d6044b7b70304bdd9ebab734d8b1c0826cbdb8Morgan Armand   FREE((void *) state->shader.tokens);
33289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   FREE(state);
33389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
334279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
335279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
336279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void
337279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulsoftpipe_set_constant_buffer(struct pipe_context *pipe,
338279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul                             uint shader, uint index,
339507337864fa80caf9f26602324d2c28dd0a75d61Marek Olšák                             struct pipe_constant_buffer *cb)
340279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul{
341279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   struct softpipe_context *softpipe = softpipe_context(pipe);
342507337864fa80caf9f26602324d2c28dd0a75d61Marek Olšák   struct pipe_resource *constants = cb ? cb->buffer : NULL;
3430b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   unsigned size;
3440b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   const void *data;
3450b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák
3460b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   if (cb && cb->user_buffer) {
347b5752e16e82d4375171d157cb116a81ea025ea7bBrian Paul      constants = softpipe_user_buffer_create(pipe->screen,
348b5752e16e82d4375171d157cb116a81ea025ea7bBrian Paul                                              (void *) cb->user_buffer,
3490b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák                                              cb->buffer_size,
3500b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák                                              PIPE_BIND_CONSTANT_BUFFER);
3510b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   }
3520b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák
3530b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   size = constants ? constants->width0 : 0;
3540b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   data = constants ? softpipe_resource(constants)->data : NULL;
355279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
356279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   assert(shader < PIPE_SHADER_TYPES);
357279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
358279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   draw_flush(softpipe->draw);
359279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
360279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   /* note: reference counting */
361279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe_resource_reference(&softpipe->constants[shader][index], constants);
362279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
363279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
364279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul      draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
365279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   }
366279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
367279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   softpipe->mapped_constants[shader][index] = data;
368279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   softpipe->const_buffer_size[shader][index] = size;
369279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
370279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   softpipe->dirty |= SP_NEW_CONSTANTS;
3710b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák
3720b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   if (cb && cb->user_buffer) {
3730b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák      pipe_resource_reference(&constants, NULL);
3740b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák   }
375279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul}
376279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
377279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
378279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulvoid
379279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulsoftpipe_init_shader_funcs(struct pipe_context *pipe)
380279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul{
381279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->create_fs_state = softpipe_create_fs_state;
382279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->bind_fs_state   = softpipe_bind_fs_state;
383279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->delete_fs_state = softpipe_delete_fs_state;
384279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
385279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->create_vs_state = softpipe_create_vs_state;
386279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->bind_vs_state   = softpipe_bind_vs_state;
387279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->delete_vs_state = softpipe_delete_vs_state;
388279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
389279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->create_gs_state = softpipe_create_gs_state;
390279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->bind_gs_state   = softpipe_bind_gs_state;
391279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->delete_gs_state = softpipe_delete_gs_state;
392279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul
393279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul   pipe->set_constant_buffer = softpipe_set_constant_buffer;
394279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul}
395