shaders_cache.c revision 544dd4b11f7be76bb00fe29a60eaf2772dcc69ca
1544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/**************************************************************************
2544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
3544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * Copyright 2009 VMware, Inc.  All Rights Reserved.
4544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
5544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * Permission is hereby granted, free of charge, to any person obtaining a
6544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * copy of this software and associated documentation files (the
7544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * "Software"), to deal in the Software without restriction, including
8544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * without limitation the rights to use, copy, modify, merge, publish,
9544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * distribute, sub license, and/or sell copies of the Software, and to
10544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * permit persons to whom the Software is furnished to do so, subject to
11544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * the following conditions:
12544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
13544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * The above copyright notice and this permission notice (including the
14544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * next paragraph) shall be included in all copies or substantial portions
15544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * of the Software.
16544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
17544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
25544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin **************************************************************************/
26544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
27544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "shaders_cache.h"
28544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
29544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "vg_context.h"
30544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
31544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_context.h"
32544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_defines.h"
33544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_inlines.h"
34544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_screen.h"
35544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_shader_tokens.h"
36544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
37544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_build.h"
38544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_dump.h"
39544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_parse.h"
40544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_util.h"
41544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_text.h"
42544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
43544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_memory.h"
44544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_math.h"
45544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_debug.h"
46544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "cso_cache/cso_hash.h"
47544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "cso_cache/cso_context.h"
48544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
49544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "VG/openvg.h"
50544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
51544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "asm_fill.h"
52544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
53544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/* Essentially we construct an ubber-shader based on the state
54544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * of the pipeline. The stages are:
55544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 1) Fill (mandatory, solid color/gradient/pattern/image draw)
56544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 2) Image composition (image mode multiply and stencil)
57544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 3) Mask
58544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 4) Extended blend (multiply/screen/darken/lighten)
59544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 5) Premultiply/Unpremultiply
60544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 6) Color transform (to black and white)
61544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin */
62544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define SHADER_STAGES 6
63544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
64544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct cached_shader {
65544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   void *driver_shader;
66544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_shader_state state;
67544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin};
68544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
69544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct shaders_cache {
70544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_context *pipe;
71544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
72544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cso_hash *hash;
73544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin};
74544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
75544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
76544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_tokens)
77544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
78544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct tgsi_token *tokens;
79544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
80544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   tokens = (struct tgsi_token *) MALLOC(num_tokens * sizeof(tokens[0]));
81544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
82544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   tgsi_text_translate(txt, tokens, num_tokens);
83544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
84544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if DEBUG_SHADERS
85544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   tgsi_dump(tokens, 0);
86544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
87544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
88544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return tokens;
89544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
90544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
91544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define ALL_FILLS (VEGA_SOLID_FILL_SHADER | \
92544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VEGA_LINEAR_GRADIENT_SHADER | \
93544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VEGA_RADIAL_GRADIENT_SHADER | \
94544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VEGA_PATTERN_SHADER         | \
95544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VEGA_IMAGE_NORMAL_SHADER)
96544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
97544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
98544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/*
99544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic const char max_shader_preamble[] =
100544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "FRAG1.1\n"
101544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL IN[0], POSITION, LINEAR\n"
102544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL IN[1], GENERIC[0], PERSPECTIVE\n"
103544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL OUT[0], COLOR, CONSTANT\n"
104544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL CONST[0..9], CONSTANT\n"
105544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL TEMP[0..9], CONSTANT\n"
106544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL SAMP[0..9], CONSTANT\n";
107544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
108544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   max_shader_preamble strlen == 175
109544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin*/
110544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define MAX_PREAMBLE 175
111544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
112544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE VGint range_min(VGint min, VGint current)
113544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
114544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (min < 0)
115544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      min = current;
116544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else
117544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      min = MIN2(min, current);
118544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return min;
119544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
120544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
121544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE VGint range_max(VGint max, VGint current)
122544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
123544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return MAX2(max, current);
124544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
125544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
126544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic void
127544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusincreate_preamble(char *txt,
128544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                const struct shader_asm_info *shaders[SHADER_STAGES],
129544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                int num_shaders)
130544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
131544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGboolean declare_input = VG_FALSE;
132544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint start_const   = -1, end_const   = 0;
133544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint start_temp    = -1, end_temp    = 0;
134544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint start_sampler = -1, end_sampler = 0;
135544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint i;
136544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint num_consts, num_temps, num_samplers;
137544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
138544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 0; i < num_shaders; ++i) {
139544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->num_consts)
140544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         start_const = range_min(start_const, shaders[i]->start_const);
141544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->num_temps)
142544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         start_temp = range_min(start_temp, shaders[i]->start_temp);
143544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->num_samplers)
144544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         start_sampler = range_min(start_sampler, shaders[i]->start_sampler);
145544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
146544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      end_const = range_max(end_const, shaders[i]->start_const +
147544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            shaders[i]->num_consts);
148544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      end_temp = range_max(end_temp, shaders[i]->start_temp +
149544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            shaders[i]->num_temps);
150544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      end_sampler = range_max(end_sampler, shaders[i]->start_sampler +
151544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            shaders[i]->num_samplers);
152544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->needs_position)
153544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         declare_input = VG_TRUE;
154544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
155544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* if they're still unitialized, initialize them */
156544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (start_const < 0)
157544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      start_const = 0;
158544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (start_temp < 0)
159544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      start_temp = 0;
160544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (start_sampler < 0)
161544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      start_sampler = 0;
162544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
163544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   num_consts   = end_const   - start_const;
164544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   num_temps    = end_temp    - start_temp;
165544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   num_samplers = end_sampler - start_sampler;
166544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* end exclusive */
167544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   --end_const;
168544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   --end_temp;
169544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   --end_sampler;
170544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
171544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   sprintf(txt, "FRAG1.1\n");
172544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
173544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (declare_input) {
174544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL IN[0], POSITION, LINEAR\n");
175544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL IN[1], GENERIC[0], PERSPECTIVE\n");
176544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
177544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
178544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* we always have a color output */
179544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   sprintf(txt + strlen(txt), "DCL OUT[0], COLOR, CONSTANT\n");
180544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
181544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (num_consts > 1)
182544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL CONST[%d..%d], CONSTANT\n", start_const, end_const);
183544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else if (num_consts == 1)
184544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL CONST[%d], CONSTANT\n", start_const);
185544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
186544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (num_temps > 1)
187544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL TEMP[%d..%d], CONSTANT\n", start_temp, end_temp);
188544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else if (num_temps > 1)
189544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL TEMP[%d], CONSTANT\n", start_temp);
190544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
191544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (num_samplers > 1)
192544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL SAMP[%d..%d], CONSTANT\n", start_sampler, end_sampler);
193544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else if (num_samplers == 1)
194544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sprintf(txt + strlen(txt), "DCL SAMP[%d], CONSTANT\n", start_sampler);
195544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
196544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
197544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic void *
198544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusincombine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders,
199544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                struct pipe_context *pipe,
200544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                struct pipe_shader_state *shader)
201544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
202544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   char *combined_txt;
203544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int combined_len = MAX_PREAMBLE;
204544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int combined_tokens = 0;
205544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int i = 0;
206544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int current_shader = 0;
207544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int current_len;
208544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
209544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 0; i < num_shaders; ++i) {
210544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      combined_len += strlen(shaders[i]->txt);
211544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      combined_tokens += shaders[i]->num_tokens;
212544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
213544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* add for the %s->TEMP[0] substitutions */
214544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   combined_len += num_shaders * 7 /*TEMP[0]*/ + 4 /*"END\n"*/;
215544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
216544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   combined_txt = (char*)malloc(combined_len);
217544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   combined_txt[0] = '\0';
218544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
219544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   create_preamble(combined_txt, shaders, num_shaders);
220544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
221544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   while (current_shader < num_shaders) {
222544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      const char temp[] = "TEMP[0]";
223544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      const char out[] = "OUT[0]";
224544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      const char *subst = temp;
225544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
226544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      current_len = strlen(combined_txt);
227544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
228544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      /* if the last shader then output */
229544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (current_shader + 1 == num_shaders)
230544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         subst = out;
231544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
232544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      snprintf(combined_txt + current_len,
233544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin               combined_len - current_len,
234544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin               shaders[current_shader]->txt,
235544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin               subst);
236544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++current_shader;
237544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
238544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
239544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
240544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   current_len = strlen(combined_txt);
241544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   snprintf(combined_txt + current_len,
242544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin            combined_len - current_len,
243544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin            "END\n");
244544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
245544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("Combined shader is : \n%s\n",
246544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                 combined_txt);
247544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
248544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   shader->tokens = tokens_from_assembly(
249544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin            combined_txt, combined_tokens);
250544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
251544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(combined_txt);
252544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
253544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return pipe->create_fs_state(pipe, shader);
254544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
255544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
256544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic void *
257544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusincreate_shader(struct pipe_context *pipe,
258544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin              int id,
259544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin              struct pipe_shader_state *shader)
260544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
261544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int idx = 0;
262544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const struct shader_asm_info * shaders[SHADER_STAGES];
263544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
264544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* the shader has to have a fill */
265544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_assert(id & ALL_FILLS);
266544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
267544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* first stage */
268544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (id & VEGA_SOLID_FILL_SHADER) {
269544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(idx == 0);
270544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[0];
271544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[0].id == VEGA_SOLID_FILL_SHADER);
272544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
273544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
274544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_LINEAR_GRADIENT_SHADER)) {
275544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(idx == 0);
276544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[1];
277544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[1].id == VEGA_LINEAR_GRADIENT_SHADER);
278544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
279544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
280544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_RADIAL_GRADIENT_SHADER)) {
281544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(idx == 0);
282544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[2];
283544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[2].id == VEGA_RADIAL_GRADIENT_SHADER);
284544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
285544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
286544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_PATTERN_SHADER)) {
287544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(idx == 0);
288544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[3].id == VEGA_PATTERN_SHADER);
289544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[3];
290544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
291544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
292544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_IMAGE_NORMAL_SHADER)) {
293544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(idx == 0);
294544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[4].id == VEGA_IMAGE_NORMAL_SHADER);
295544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[4];
296544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
297544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
298544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
299544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* second stage */
300544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_IMAGE_MULTIPLY_SHADER)) {
301544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[5].id == VEGA_IMAGE_MULTIPLY_SHADER);
302544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[5];
303544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
304544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } else if ((id & VEGA_IMAGE_STENCIL_SHADER)) {
305544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[6].id == VEGA_IMAGE_STENCIL_SHADER);
306544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[6];
307544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
308544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
309544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
310544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* third stage */
311544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_MASK_SHADER)) {
312544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(idx == 1);
313544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[7].id == VEGA_MASK_SHADER);
314544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[7];
315544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
316544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
317544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
318544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* fourth stage */
319544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_BLEND_MULTIPLY_SHADER)) {
320544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[8].id == VEGA_BLEND_MULTIPLY_SHADER);
321544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[8];
322544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
323544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } else if ((id & VEGA_BLEND_SCREEN_SHADER)) {
324544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[9].id == VEGA_BLEND_SCREEN_SHADER);
325544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[9];
326544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
327544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } else if ((id & VEGA_BLEND_DARKEN_SHADER)) {
328544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[10].id == VEGA_BLEND_DARKEN_SHADER);
329544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[10];
330544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
331544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } else if ((id & VEGA_BLEND_LIGHTEN_SHADER)) {
332544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[11].id == VEGA_BLEND_LIGHTEN_SHADER);
333544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[11];
334544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
335544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
336544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
337544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* fifth stage */
338544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_PREMULTIPLY_SHADER)) {
339544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[12].id == VEGA_PREMULTIPLY_SHADER);
340544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[12];
341544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
342544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } else if ((id & VEGA_UNPREMULTIPLY_SHADER)) {
343544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[13].id == VEGA_UNPREMULTIPLY_SHADER);
344544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[13];
345544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
346544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
347544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
348544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* sixth stage */
349544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if ((id & VEGA_BW_SHADER)) {
350544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert(shaders_asm[14].id == VEGA_BW_SHADER);
351544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shaders[idx] = &shaders_asm[14];
352544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++idx;
353544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
354544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
355544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return combine_shaders(shaders, idx, pipe, shader);
356544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
357544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
358544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/*************************************************/
359544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
360544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct shaders_cache * shaders_cache_create(struct vg_context *vg)
361544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
362544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct shaders_cache *sc = CALLOC_STRUCT(shaders_cache);
363544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
364544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   sc->pipe = vg;
365544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   sc->hash = cso_hash_create();
366544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
367544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return sc;
368544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
369544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
370544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid shaders_cache_destroy(struct shaders_cache *sc)
371544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
372544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cso_hash_iter iter = cso_hash_first_node(sc->hash);
373544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
374544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   while (!cso_hash_iter_is_null(iter)) {
375544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct cached_shader *cached =
376544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         (struct cached_shader *)cso_hash_iter_data(iter);
377544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_delete_fragment_shader(sc->pipe->cso_context,
378544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                 cached->driver_shader);
379544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      iter = cso_hash_erase(sc->hash, iter);
380544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
381544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
382544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   cso_hash_delete(sc->hash);
383544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(sc);
384544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
385544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
386544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid * shaders_cache_fill(struct shaders_cache *sc,
387544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                          int shader_key)
388544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
389544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint key = shader_key;
390544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cached_shader *cached;
391544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cso_hash_iter iter = cso_hash_find(sc->hash, key);
392544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
393544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (cso_hash_iter_is_null(iter)) {
394544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cached = CALLOC_STRUCT(cached_shader);
395544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cached->driver_shader = create_shader(sc->pipe->pipe, key, &cached->state);
396544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
397544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_hash_insert(sc->hash, key, cached);
398544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
399544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return cached->driver_shader;
400544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
401544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
402544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   cached = (struct cached_shader *)cso_hash_iter_data(iter);
403544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
404544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   assert(cached->driver_shader);
405544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return cached->driver_shader;
406544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
407544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
408544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct vg_shader * shader_create_from_text(struct pipe_context *pipe,
409544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                           const char *txt, int num_tokens,
410544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                           int type)
411544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
412544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_shader *shader = (struct vg_shader *)malloc(
413544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sizeof(struct vg_shader));
414544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct tgsi_token *tokens = tokens_from_assembly(txt, num_tokens);
415544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_shader_state state;
416544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
417544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_assert(type == PIPE_SHADER_VERTEX ||
418544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                type == PIPE_SHADER_FRAGMENT);
419544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
420544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   state.tokens = tokens;
421544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   shader->type = type;
422544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   shader->tokens = tokens;
423544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
424544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (type == PIPE_SHADER_FRAGMENT)
425544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shader->driver = pipe->create_fs_state(pipe, &state);
426544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else
427544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shader->driver = pipe->create_vs_state(pipe, &state);
428544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return shader;
429544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
430544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
431544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid vg_shader_destroy(struct vg_context *ctx, struct vg_shader *shader)
432544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
433544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (shader->type == PIPE_SHADER_FRAGMENT)
434544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_delete_fragment_shader(ctx->cso_context, shader->driver);
435544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else
436544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_delete_vertex_shader(ctx->cso_context, shader->driver);
437544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(shader->tokens);
438544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(shader);
439544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
440