1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.  All Rights Reserved.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "shaders_cache.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_context.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_build.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_dump.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_util.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_text.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "cso_cache/cso_hash.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "cso_cache/cso_context.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "VG/openvg.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "asm_fill.h"
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Essentially we construct an ubber-shader based on the state
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the pipeline. The stages are:
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1) Paint generation (color/gradient/pattern)
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2) Image composition (normal/multiply/stencil)
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3) Color transform
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4) Per-channel alpha generation
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5) Extended blend (multiply/screen/darken/lighten)
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6) Mask
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7) Premultiply/Unpremultiply
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 8) Color transform (to black and white)
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHADER_STAGES 8
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cached_shader {
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *driver_shader;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_shader_state state;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct shaders_cache {
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_context *pipe;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cso_hash *hash;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_tokens)
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_token *tokens;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tokens = (struct tgsi_token *) MALLOC(num_tokens * sizeof(tokens[0]));
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tgsi_text_translate(txt, tokens, num_tokens);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_SHADERS
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tgsi_dump(tokens, 0);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return tokens;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char max_shader_preamble[] =
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "FRAG\n"
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "DCL IN[0], POSITION, LINEAR\n"
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "DCL IN[1], GENERIC[0], PERSPECTIVE\n"
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "DCL OUT[0], COLOR, CONSTANT\n"
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "DCL CONST[0..9], CONSTANT\n"
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "DCL TEMP[0..9], CONSTANT\n"
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   "DCL SAMP[0..9], CONSTANT\n";
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   max_shader_preamble strlen == 175
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*/
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_PREAMBLE 175
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGint range_min(VGint min, VGint current)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min < 0)
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      min = current;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      min = MIN2(min, current);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return min;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGint range_max(VGint max, VGint current)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return MAX2(max, current);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcombine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders,
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                struct pipe_context *pipe,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                struct pipe_shader_state *shader)
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGboolean declare_input = VG_FALSE;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint start_const   = -1, end_const   = 0;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint start_temp    = -1, end_temp    = 0;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint start_sampler = -1, end_sampler = 0;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint i, current_shader = 0;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint num_consts, num_temps, num_samplers;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src in[2];
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src *sampler = NULL;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src *constant = NULL;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst out, *temp = NULL;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *p = NULL;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < num_shaders; ++i) {
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shaders[i]->num_consts)
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         start_const = range_min(start_const, shaders[i]->start_const);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shaders[i]->num_temps)
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         start_temp = range_min(start_temp, shaders[i]->start_temp);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shaders[i]->num_samplers)
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         start_sampler = range_min(start_sampler, shaders[i]->start_sampler);
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      end_const = range_max(end_const, shaders[i]->start_const +
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shaders[i]->num_consts);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      end_temp = range_max(end_temp, shaders[i]->start_temp +
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shaders[i]->num_temps);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      end_sampler = range_max(end_sampler, shaders[i]->start_sampler +
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shaders[i]->num_samplers);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shaders[i]->needs_position)
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         declare_input = VG_TRUE;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* if they're still unitialized, initialize them */
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (start_const < 0)
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      start_const = 0;
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (start_temp < 0)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      start_temp = 0;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (start_sampler < 0)
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       start_sampler = 0;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_consts   = end_const   - start_const;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_temps    = end_temp    - start_temp;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_samplers = end_sampler - start_sampler;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ureg)
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return NULL;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (declare_input) {
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      in[0] = ureg_DECL_fs_input(ureg,
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 TGSI_SEMANTIC_POSITION,
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 0,
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 TGSI_INTERPOLATE_LINEAR);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      in[1] = ureg_DECL_fs_input(ureg,
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 TGSI_SEMANTIC_GENERIC,
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 0,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 TGSI_INTERPOLATE_PERSPECTIVE);
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* we always have a color output */
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_consts >= 1) {
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      constant = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_const);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = start_const; i < end_const; i++) {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         constant[i] = ureg_DECL_constant(ureg, i);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_temps >= 1) {
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp = (struct ureg_dst *) malloc(sizeof(struct ureg_dst) * end_temp);
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = start_temp; i < end_temp; i++) {
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         temp[i] = ureg_DECL_temporary(ureg);
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_samplers >= 1) {
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sampler = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_sampler);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = start_sampler; i < end_sampler; i++) {
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sampler[i] = ureg_DECL_sampler(ureg, i);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (current_shader < num_shaders) {
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((current_shader + 1) == num_shaders) {
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shaders[current_shader]->func(ureg,
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       &out,
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       in,
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       sampler,
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       temp,
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       constant);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shaders[current_shader]->func(ureg,
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &temp[0],
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      in,
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      sampler,
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      temp,
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      constant);
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      current_shader++;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ureg_END(ureg);
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->tokens = ureg_finalize(ureg);
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!shader->tokens)
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   p = pipe->create_fs_state(pipe, shader);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_temps >= 1) {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = start_temp; i < end_temp; i++) {
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_release_temporary(ureg, temp[i]);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ureg_destroy(ureg);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (temp)
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(temp);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (constant)
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(constant);
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (sampler)
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(sampler);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return p;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_shader(struct pipe_context *pipe,
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              int id,
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              struct pipe_shader_state *shader)
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int idx = 0, sh;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct shader_asm_info * shaders[SHADER_STAGES];
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* first stage */
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_PAINT_SHADER(id);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh << SHADERS_PAINT_SHIFT) {
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_SOLID_FILL_SHADER:
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_LINEAR_GRADIENT_SHADER:
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_RADIAL_GRADIENT_SHADER:
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_PATTERN_SHADER:
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_PAINT_DEGENERATE_SHADER:
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* second stage */
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_IMAGE_SHADER(id);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_IMAGE_NORMAL_SHADER:
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_IMAGE_MULTIPLY_SHADER:
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_IMAGE_STENCIL_SHADER:
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_image_asm[(sh >> SHADERS_IMAGE_SHIFT) - 1];
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sanity check */
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(idx == ((!sh || sh == VEGA_IMAGE_NORMAL_SHADER) ? 1 : 2));
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* third stage */
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_COLOR_TRANSFORM_SHADER(id);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_COLOR_TRANSFORM_SHADER:
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_color_transform_asm[
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (sh >> SHADERS_COLOR_TRANSFORM_SHIFT) - 1];
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* fourth stage */
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_ALPHA_SHADER(id);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_ALPHA_NORMAL_SHADER:
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_ALPHA_PER_CHANNEL_SHADER:
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_alpha_asm[
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (sh >> SHADERS_ALPHA_SHIFT) - 1];
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* fifth stage */
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_BLEND_SHADER(id);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_SRC_SHADER:
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_SRC_OVER_SHADER:
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_DST_OVER_SHADER:
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_SRC_IN_SHADER:
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_DST_IN_SHADER:
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_MULTIPLY_SHADER:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_SCREEN_SHADER:
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_DARKEN_SHADER:
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_LIGHTEN_SHADER:
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BLEND_ADDITIVE_SHADER:
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sixth stage */
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_MASK_SHADER(id);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_MASK_SHADER:
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_mask_asm[(sh >> SHADERS_MASK_SHIFT) - 1];
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* seventh stage */
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_PREMULTIPLY_SHADER(id);
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_PREMULTIPLY_SHADER:
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_UNPREMULTIPLY_SHADER:
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_premultiply_asm[
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (sh >> SHADERS_PREMULTIPLY_SHIFT) - 1];
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* eighth stage */
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sh = SHADERS_GET_BW_SHADER(id);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sh) {
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case VEGA_BW_SHADER:
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shaders[idx] = &shaders_bw_asm[(sh >> SHADERS_BW_SHIFT) - 1];
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(shaders[idx]->id == sh);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      idx++;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return combine_shaders(shaders, idx, pipe, shader);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*************************************************/
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct shaders_cache * shaders_cache_create(struct vg_context *vg)
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct shaders_cache *sc = CALLOC_STRUCT(shaders_cache);
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sc->pipe = vg;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sc->hash = cso_hash_create();
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return sc;
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid shaders_cache_destroy(struct shaders_cache *sc)
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cso_hash_iter iter = cso_hash_first_node(sc->hash);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (!cso_hash_iter_is_null(iter)) {
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct cached_shader *cached =
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (struct cached_shader *)cso_hash_iter_data(iter);
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cso_delete_fragment_shader(sc->pipe->cso_context,
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 cached->driver_shader);
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      iter = cso_hash_erase(sc->hash, iter);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cso_hash_delete(sc->hash);
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(sc);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * shaders_cache_fill(struct shaders_cache *sc,
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          int shader_key)
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VGint key = shader_key;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cached_shader *cached;
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cso_hash_iter iter = cso_hash_find(sc->hash, key);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cso_hash_iter_is_null(iter)) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cached = CALLOC_STRUCT(cached_shader);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cached->driver_shader = create_shader(sc->pipe->pipe, key, &cached->state);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cso_hash_insert(sc->hash, key, cached);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return cached->driver_shader;
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cached = (struct cached_shader *)cso_hash_iter_data(iter);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(cached->driver_shader);
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return cached->driver_shader;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct vg_shader * shader_create_from_text(struct pipe_context *pipe,
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           const char *txt, int num_tokens,
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           int type)
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vg_shader *shader = (struct vg_shader *)MALLOC(
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sizeof(struct vg_shader));
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_token *tokens = tokens_from_assembly(txt, num_tokens);
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_shader_state state;
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_assert(type == PIPE_SHADER_VERTEX ||
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                type == PIPE_SHADER_FRAGMENT);
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state.tokens = tokens;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&state.stream_output, 0, sizeof(state.stream_output));
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->type = type;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->tokens = tokens;
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type == PIPE_SHADER_FRAGMENT)
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->driver = pipe->create_fs_state(pipe, &state);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->driver = pipe->create_vs_state(pipe, &state);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid vg_shader_destroy(struct vg_context *ctx, struct vg_shader *shader)
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->type == PIPE_SHADER_FRAGMENT)
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cso_delete_fragment_shader(ctx->cso_context, shader->driver);
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cso_delete_vertex_shader(ctx->cso_context, shader->driver);
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(shader->tokens);
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(shader);
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
464