shaders_cache.c revision 213e288e78bf5b0fb0a996cc17dfd959756c2c53
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_shader_tokens.h"
34544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
35544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_build.h"
36544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_dump.h"
37544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_parse.h"
38544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_util.h"
39544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "tgsi/tgsi_text.h"
40544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
41544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_memory.h"
42544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_math.h"
43544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_debug.h"
44544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "cso_cache/cso_hash.h"
45544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "cso_cache/cso_context.h"
46544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
47544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "VG/openvg.h"
48544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
49544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "asm_fill.h"
50544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
51544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/* Essentially we construct an ubber-shader based on the state
52544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * of the pipeline. The stages are:
53213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu * 1) Paint generation (color/gradient/pattern)
54213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu * 2) Image composition (normal/multiply/stencil)
55544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 3) Mask
56544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 4) Extended blend (multiply/screen/darken/lighten)
57544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 5) Premultiply/Unpremultiply
58544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * 6) Color transform (to black and white)
59544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin */
60544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define SHADER_STAGES 6
61544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
62544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct cached_shader {
63544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   void *driver_shader;
64544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_shader_state state;
65544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin};
66544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
67544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct shaders_cache {
68544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_context *pipe;
69544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
70544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cso_hash *hash;
71544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin};
72544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
73544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
74544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_tokens)
75544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
76544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct tgsi_token *tokens;
77544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
78544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   tokens = (struct tgsi_token *) MALLOC(num_tokens * sizeof(tokens[0]));
79544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
80544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   tgsi_text_translate(txt, tokens, num_tokens);
81544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
82544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if DEBUG_SHADERS
83544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   tgsi_dump(tokens, 0);
84544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
85544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
86544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return tokens;
87544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
88544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
89544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/*
90544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic const char max_shader_preamble[] =
915285de7c0fc067dc036a5b421140a696ce2cabbfMichal Krol   "FRAG\n"
92544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL IN[0], POSITION, LINEAR\n"
93544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL IN[1], GENERIC[0], PERSPECTIVE\n"
94544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL OUT[0], COLOR, CONSTANT\n"
95544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL CONST[0..9], CONSTANT\n"
96544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL TEMP[0..9], CONSTANT\n"
97544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   "DCL SAMP[0..9], CONSTANT\n";
98544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
99544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   max_shader_preamble strlen == 175
100544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin*/
101544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define MAX_PREAMBLE 175
102544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
103544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE VGint range_min(VGint min, VGint current)
104544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
105544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (min < 0)
106544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      min = current;
107544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else
108544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      min = MIN2(min, current);
109544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return min;
110544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
111544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
112544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE VGint range_max(VGint max, VGint current)
113544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
114544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return MAX2(max, current);
115544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
116544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
117301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveirastatic void *
118301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveiracombine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders,
119301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                struct pipe_context *pipe,
120301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                struct pipe_shader_state *shader)
121544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
122544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGboolean declare_input = VG_FALSE;
123544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint start_const   = -1, end_const   = 0;
124544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint start_temp    = -1, end_temp    = 0;
125544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint start_sampler = -1, end_sampler = 0;
126301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   VGint i, current_shader = 0;
127544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint num_consts, num_temps, num_samplers;
128301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   struct ureg_program *ureg;
129301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   struct ureg_src in[2];
130301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   struct ureg_src *sampler = NULL;
131301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   struct ureg_src *constant = NULL;
132301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   struct ureg_dst out, *temp = NULL;
133301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   void *p = NULL;
134544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
135544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 0; i < num_shaders; ++i) {
136544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->num_consts)
137544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         start_const = range_min(start_const, shaders[i]->start_const);
138544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->num_temps)
139544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         start_temp = range_min(start_temp, shaders[i]->start_temp);
140544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->num_samplers)
141544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         start_sampler = range_min(start_sampler, shaders[i]->start_sampler);
142544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
143544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      end_const = range_max(end_const, shaders[i]->start_const +
144544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            shaders[i]->num_consts);
145544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      end_temp = range_max(end_temp, shaders[i]->start_temp +
146544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            shaders[i]->num_temps);
147544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      end_sampler = range_max(end_sampler, shaders[i]->start_sampler +
148544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            shaders[i]->num_samplers);
149544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (shaders[i]->needs_position)
150544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         declare_input = VG_TRUE;
151544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
152544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* if they're still unitialized, initialize them */
153544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (start_const < 0)
154544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      start_const = 0;
155544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (start_temp < 0)
156544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      start_temp = 0;
157544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (start_sampler < 0)
158301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira       start_sampler = 0;
159544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
160544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   num_consts   = end_const   - start_const;
161544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   num_temps    = end_temp    - start_temp;
162544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   num_samplers = end_sampler - start_sampler;
163544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
164301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
165301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (!ureg)
166301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira       return NULL;
167544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
168544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (declare_input) {
169301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      in[0] = ureg_DECL_fs_input(ureg,
170301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                 TGSI_SEMANTIC_POSITION,
171301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                 0,
172301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                 TGSI_INTERPOLATE_LINEAR);
173301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      in[1] = ureg_DECL_fs_input(ureg,
174301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                 TGSI_SEMANTIC_GENERIC,
175301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                 0,
176301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                 TGSI_INTERPOLATE_PERSPECTIVE);
177544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
178544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
179544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* we always have a color output */
180301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
181544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
182301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (num_consts >= 1) {
183301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      constant = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_const);
184301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      for (i = start_const; i < end_const; i++) {
185301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira         constant[i] = ureg_DECL_constant(ureg, i);
186301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      }
187544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
188544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
189544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
190301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (num_temps >= 1) {
191301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      temp = (struct ureg_dst *) malloc(sizeof(struct ureg_dst) * end_temp);
192301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      for (i = start_temp; i < end_temp; i++) {
193301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira         temp[i] = ureg_DECL_temporary(ureg);
194301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      }
195301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   }
196544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
197301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (num_samplers >= 1) {
198301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      sampler = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_sampler);
199301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      for (i = start_sampler; i < end_sampler; i++) {
200301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira         sampler[i] = ureg_DECL_sampler(ureg, i);
201301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      }
202301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   }
203544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
204544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   while (current_shader < num_shaders) {
205301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      if ((current_shader + 1) == num_shaders) {
206301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira         shaders[current_shader]->func(ureg,
207301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                       &out,
208301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                       in,
209301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                       sampler,
210301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                       temp,
211301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                       constant);
212301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      } else {
213301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira         shaders[current_shader]->func(ureg,
214301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                      &temp[0],
215301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                      in,
216301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                      sampler,
217301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                      temp,
218301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira                                      constant);
219301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      }
220301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      current_shader++;
221544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
222544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
223301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   ureg_END(ureg);
224544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
225301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   shader->tokens = ureg_finalize(ureg);
226301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if(!shader->tokens)
227301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      return NULL;
228544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
229301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   p = pipe->create_fs_state(pipe, shader);
230301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   ureg_destroy(ureg);
231544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
232301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (num_temps >= 1) {
233301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      for (i = start_temp; i < end_temp; i++) {
234301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira         ureg_release_temporary(ureg, temp[i]);
235301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      }
236301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   }
237544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
238301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (temp)
239301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      free(temp);
240301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (constant)
241301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      free(constant);
242301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   if (sampler)
243301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira      free(sampler);
244544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
245301a9437cc5d89686391e5722b952f52df274ab3Igor Oliveira   return p;
246544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
247544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
248544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic void *
249544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusincreate_shader(struct pipe_context *pipe,
250544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin              int id,
251544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin              struct pipe_shader_state *shader)
252544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
253213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   int idx = 0, sh;
254544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const struct shader_asm_info * shaders[SHADER_STAGES];
255544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
256544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* first stage */
257213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   sh = SHADERS_GET_PAINT_SHADER(id);
258213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   switch (sh << SHADERS_PAINT_SHIFT) {
259213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_SOLID_FILL_SHADER:
260213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_LINEAR_GRADIENT_SHADER:
261213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_RADIAL_GRADIENT_SHADER:
262213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_PATTERN_SHADER:
263213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
264213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      assert(shaders[idx]->id == sh);
265213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      idx++;
266213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
267213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   default:
268213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
269544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
270544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
271544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* second stage */
272213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   sh = SHADERS_GET_IMAGE_SHADER(id);
273213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   switch (sh) {
274213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_IMAGE_NORMAL_SHADER:
275213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_IMAGE_MULTIPLY_SHADER:
276213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_IMAGE_STENCIL_SHADER:
277213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      shaders[idx] = &shaders_image_asm[(sh >> SHADERS_IMAGE_SHIFT) - 1];
278213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      assert(shaders[idx]->id == sh);
279213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      idx++;
280213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
281213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   default:
282213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
283544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
284544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
285213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   /* sanity check */
286213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   assert(idx == ((!sh || sh == VEGA_IMAGE_NORMAL_SHADER) ? 1 : 2));
287213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu
288544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* third stage */
289213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   sh = SHADERS_GET_MASK_SHADER(id);
290213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   switch (sh) {
291213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_MASK_SHADER:
292213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      shaders[idx] = &shaders_mask_asm[(sh >> SHADERS_MASK_SHIFT) - 1];
293213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      assert(shaders[idx]->id == sh);
294213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      idx++;
295213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
296213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   default:
297213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
298544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
299544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
300544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* fourth stage */
301213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   sh = SHADERS_GET_BLEND_SHADER(id);
302213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   switch (sh) {
303213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_BLEND_MULTIPLY_SHADER:
304213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_BLEND_SCREEN_SHADER:
305213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_BLEND_DARKEN_SHADER:
306213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_BLEND_LIGHTEN_SHADER:
307213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
308213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      assert(shaders[idx]->id == sh);
309213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      idx++;
310213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
311213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   default:
312213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
313544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
314544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
315544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* fifth stage */
316213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   sh = SHADERS_GET_PREMULTIPLY_SHADER(id);
317213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   switch (sh) {
318213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_PREMULTIPLY_SHADER:
319213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_UNPREMULTIPLY_SHADER:
320213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      shaders[idx] = &shaders_premultiply_asm[
321213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu         (sh >> SHADERS_PREMULTIPLY_SHIFT) - 1];
322213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      assert(shaders[idx]->id == sh);
323213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      idx++;
324213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
325213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   default:
326213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
327544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
328544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
329544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* sixth stage */
330213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   sh = SHADERS_GET_BW_SHADER(id);
331213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   switch (sh) {
332213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   case VEGA_BW_SHADER:
333213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      shaders[idx] = &shaders_bw_asm[(sh >> SHADERS_BW_SHIFT) - 1];
334213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      assert(shaders[idx]->id == sh);
335213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      idx++;
336213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
337213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu   default:
338213e288e78bf5b0fb0a996cc17dfd959756c2c53Chia-I Wu      break;
339544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
340544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
341544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return combine_shaders(shaders, idx, pipe, shader);
342544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
343544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
344544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/*************************************************/
345544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
346544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct shaders_cache * shaders_cache_create(struct vg_context *vg)
347544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
348544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct shaders_cache *sc = CALLOC_STRUCT(shaders_cache);
349544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
350544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   sc->pipe = vg;
351544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   sc->hash = cso_hash_create();
352544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
353544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return sc;
354544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
355544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
356544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid shaders_cache_destroy(struct shaders_cache *sc)
357544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
358544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cso_hash_iter iter = cso_hash_first_node(sc->hash);
359544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
360544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   while (!cso_hash_iter_is_null(iter)) {
361544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct cached_shader *cached =
362544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         (struct cached_shader *)cso_hash_iter_data(iter);
363544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_delete_fragment_shader(sc->pipe->cso_context,
364544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                 cached->driver_shader);
365544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      iter = cso_hash_erase(sc->hash, iter);
366544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
367544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
368544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   cso_hash_delete(sc->hash);
369f914cd1796845164109c837a111c39ba64852ad4nobled   FREE(sc);
370544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
371544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
372544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid * shaders_cache_fill(struct shaders_cache *sc,
373544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                          int shader_key)
374544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
375544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint key = shader_key;
376544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cached_shader *cached;
377544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct cso_hash_iter iter = cso_hash_find(sc->hash, key);
378544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
379544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (cso_hash_iter_is_null(iter)) {
380544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cached = CALLOC_STRUCT(cached_shader);
381544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cached->driver_shader = create_shader(sc->pipe->pipe, key, &cached->state);
382544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
383544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_hash_insert(sc->hash, key, cached);
384544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
385544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return cached->driver_shader;
386544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
387544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
388544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   cached = (struct cached_shader *)cso_hash_iter_data(iter);
389544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
390544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   assert(cached->driver_shader);
391544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return cached->driver_shader;
392544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
393544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
394544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct vg_shader * shader_create_from_text(struct pipe_context *pipe,
395544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                           const char *txt, int num_tokens,
396544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                           int type)
397544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
3982d8e70fcd57b23786e3f4196f35440ed1861a98bChia-I Wu   struct vg_shader *shader = (struct vg_shader *)MALLOC(
399544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      sizeof(struct vg_shader));
400544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct tgsi_token *tokens = tokens_from_assembly(txt, num_tokens);
401544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_shader_state state;
402544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
403544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_assert(type == PIPE_SHADER_VERTEX ||
404544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                type == PIPE_SHADER_FRAGMENT);
405544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
406544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   state.tokens = tokens;
407544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   shader->type = type;
408544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   shader->tokens = tokens;
409544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
410544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (type == PIPE_SHADER_FRAGMENT)
411544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shader->driver = pipe->create_fs_state(pipe, &state);
412544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else
413544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      shader->driver = pipe->create_vs_state(pipe, &state);
414544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return shader;
415544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
416544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
417544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid vg_shader_destroy(struct vg_context *ctx, struct vg_shader *shader)
418544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
419544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (shader->type == PIPE_SHADER_FRAGMENT)
420544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_delete_fragment_shader(ctx->cso_context, shader->driver);
421544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   else
422544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      cso_delete_vertex_shader(ctx->cso_context, shader->driver);
423f914cd1796845164109c837a111c39ba64852ad4nobled   FREE(shader->tokens);
424f914cd1796845164109c837a111c39ba64852ad4nobled   FREE(shader);
425544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
426