1b8e80941Smrg/*
2b8e80941Smrg * Copyright (c) 2012-2015 Etnaviv Project
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the
12b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions
13b8e80941Smrg * of the Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Wladimir J. van der Laan <laanwj@gmail.com>
25b8e80941Smrg */
26b8e80941Smrg
27b8e80941Smrg#include "etnaviv_shader.h"
28b8e80941Smrg
29b8e80941Smrg#include "etnaviv_compiler.h"
30b8e80941Smrg#include "etnaviv_context.h"
31b8e80941Smrg#include "etnaviv_debug.h"
32b8e80941Smrg#include "etnaviv_screen.h"
33b8e80941Smrg#include "etnaviv_util.h"
34b8e80941Smrg
35b8e80941Smrg#include "tgsi/tgsi_parse.h"
36b8e80941Smrg#include "util/u_math.h"
37b8e80941Smrg#include "util/u_memory.h"
38b8e80941Smrg
39b8e80941Smrg/* Upload shader code to bo, if not already done */
40b8e80941Smrgstatic bool etna_icache_upload_shader(struct etna_context *ctx, struct etna_shader_variant *v)
41b8e80941Smrg{
42b8e80941Smrg   if (v->bo)
43b8e80941Smrg      return true;
44b8e80941Smrg   v->bo = etna_bo_new(ctx->screen->dev, v->code_size*4, DRM_ETNA_GEM_CACHE_WC);
45b8e80941Smrg   if (!v->bo)
46b8e80941Smrg      return false;
47b8e80941Smrg
48b8e80941Smrg   void *buf = etna_bo_map(v->bo);
49b8e80941Smrg   etna_bo_cpu_prep(v->bo, DRM_ETNA_PREP_WRITE);
50b8e80941Smrg   memcpy(buf, v->code, v->code_size*4);
51b8e80941Smrg   etna_bo_cpu_fini(v->bo);
52b8e80941Smrg   DBG("Uploaded %s of %u words to bo %p", v->processor == PIPE_SHADER_FRAGMENT ? "fs":"vs", v->code_size, v->bo);
53b8e80941Smrg   return true;
54b8e80941Smrg}
55b8e80941Smrg
56b8e80941Smrg/* Link vs and fs together: fill in shader_state from vs and fs
57b8e80941Smrg * as this function is called every time a new fs or vs is bound, the goal is to
58b8e80941Smrg * do little processing as possible here, and to precompute as much as possible in
59b8e80941Smrg * the vs/fs shader_object.
60b8e80941Smrg *
61b8e80941Smrg * XXX we could cache the link result for a certain set of VS/PS; usually a pair
62b8e80941Smrg * of VS and PS will be used together anyway.
63b8e80941Smrg */
64b8e80941Smrgstatic bool
65b8e80941Smrgetna_link_shaders(struct etna_context *ctx, struct compiled_shader_state *cs,
66b8e80941Smrg                  struct etna_shader_variant *vs, struct etna_shader_variant *fs)
67b8e80941Smrg{
68b8e80941Smrg   struct etna_shader_link_info link = { };
69b8e80941Smrg
70b8e80941Smrg   assert(vs->processor == PIPE_SHADER_VERTEX);
71b8e80941Smrg   assert(fs->processor == PIPE_SHADER_FRAGMENT);
72b8e80941Smrg
73b8e80941Smrg#ifdef DEBUG
74b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_DUMP_SHADERS)) {
75b8e80941Smrg      etna_dump_shader(vs);
76b8e80941Smrg      etna_dump_shader(fs);
77b8e80941Smrg   }
78b8e80941Smrg#endif
79b8e80941Smrg
80b8e80941Smrg   if (etna_link_shader(&link, vs, fs)) {
81b8e80941Smrg      /* linking failed: some fs inputs do not have corresponding
82b8e80941Smrg       * vs outputs */
83b8e80941Smrg      assert(0);
84b8e80941Smrg
85b8e80941Smrg      return false;
86b8e80941Smrg   }
87b8e80941Smrg
88b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_LINKER_MSGS)) {
89b8e80941Smrg      debug_printf("link result:\n");
90b8e80941Smrg      debug_printf("  vs  -> fs  comps use     pa_attr\n");
91b8e80941Smrg
92b8e80941Smrg      for (int idx = 0; idx < link.num_varyings; ++idx)
93b8e80941Smrg         debug_printf("  t%-2u -> t%-2u %-5.*s %u,%u,%u,%u 0x%08x\n",
94b8e80941Smrg                      link.varyings[idx].reg, idx + 1,
95b8e80941Smrg                      link.varyings[idx].num_components, "xyzw",
96b8e80941Smrg                      link.varyings[idx].use[0], link.varyings[idx].use[1],
97b8e80941Smrg                      link.varyings[idx].use[2], link.varyings[idx].use[3],
98b8e80941Smrg                      link.varyings[idx].pa_attributes);
99b8e80941Smrg   }
100b8e80941Smrg
101b8e80941Smrg   /* set last_varying_2x flag if the last varying has 1 or 2 components */
102b8e80941Smrg   bool last_varying_2x = false;
103b8e80941Smrg   if (link.num_varyings > 0 && link.varyings[link.num_varyings - 1].num_components <= 2)
104b8e80941Smrg      last_varying_2x = true;
105b8e80941Smrg
106b8e80941Smrg   cs->RA_CONTROL = VIVS_RA_CONTROL_UNK0 |
107b8e80941Smrg                    COND(last_varying_2x, VIVS_RA_CONTROL_LAST_VARYING_2X);
108b8e80941Smrg
109b8e80941Smrg   cs->PA_ATTRIBUTE_ELEMENT_COUNT = VIVS_PA_ATTRIBUTE_ELEMENT_COUNT_COUNT(link.num_varyings);
110b8e80941Smrg   for (int idx = 0; idx < link.num_varyings; ++idx)
111b8e80941Smrg      cs->PA_SHADER_ATTRIBUTES[idx] = link.varyings[idx].pa_attributes;
112b8e80941Smrg
113b8e80941Smrg   cs->VS_END_PC = vs->code_size / 4;
114b8e80941Smrg   cs->VS_OUTPUT_COUNT = 1 + link.num_varyings; /* position + varyings */
115b8e80941Smrg
116b8e80941Smrg   /* vs outputs (varyings) */
117b8e80941Smrg   DEFINE_ETNA_BITARRAY(vs_output, 16, 8) = {0};
118b8e80941Smrg   int varid = 0;
119b8e80941Smrg   etna_bitarray_set(vs_output, 8, varid++, vs->vs_pos_out_reg);
120b8e80941Smrg   for (int idx = 0; idx < link.num_varyings; ++idx)
121b8e80941Smrg      etna_bitarray_set(vs_output, 8, varid++, link.varyings[idx].reg);
122b8e80941Smrg   if (vs->vs_pointsize_out_reg >= 0)
123b8e80941Smrg      etna_bitarray_set(vs_output, 8, varid++, vs->vs_pointsize_out_reg); /* pointsize is last */
124b8e80941Smrg
125b8e80941Smrg   for (int idx = 0; idx < ARRAY_SIZE(cs->VS_OUTPUT); ++idx)
126b8e80941Smrg      cs->VS_OUTPUT[idx] = vs_output[idx];
127b8e80941Smrg
128b8e80941Smrg   if (vs->vs_pointsize_out_reg != -1) {
129b8e80941Smrg      /* vertex shader outputs point coordinate, provide extra output and make
130b8e80941Smrg       * sure PA config is
131b8e80941Smrg       * not masked */
132b8e80941Smrg      cs->PA_CONFIG = ~0;
133b8e80941Smrg      cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT + 1;
134b8e80941Smrg   } else {
135b8e80941Smrg      /* vertex shader does not output point coordinate, make sure thate
136b8e80941Smrg       * POINT_SIZE_ENABLE is masked
137b8e80941Smrg       * and no extra output is given */
138b8e80941Smrg      cs->PA_CONFIG = ~VIVS_PA_CONFIG_POINT_SIZE_ENABLE;
139b8e80941Smrg      cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT;
140b8e80941Smrg   }
141b8e80941Smrg
142b8e80941Smrg   cs->VS_LOAD_BALANCING = vs->vs_load_balancing;
143b8e80941Smrg   cs->VS_START_PC = 0;
144b8e80941Smrg
145b8e80941Smrg   cs->PS_END_PC = fs->code_size / 4;
146b8e80941Smrg   cs->PS_OUTPUT_REG = fs->ps_color_out_reg;
147b8e80941Smrg   cs->PS_INPUT_COUNT =
148b8e80941Smrg      VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 1) | /* Number of inputs plus position */
149b8e80941Smrg      VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8);
150b8e80941Smrg   cs->PS_TEMP_REGISTER_CONTROL =
151b8e80941Smrg      VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 1));
152b8e80941Smrg   cs->PS_CONTROL = VIVS_PS_CONTROL_UNK1; /* XXX when can we set BYPASS? */
153b8e80941Smrg   cs->PS_START_PC = 0;
154b8e80941Smrg
155b8e80941Smrg   /* Precompute PS_INPUT_COUNT and TEMP_REGISTER_CONTROL in the case of MSAA
156b8e80941Smrg    * mode, avoids some fumbling in sync_context. */
157b8e80941Smrg   cs->PS_INPUT_COUNT_MSAA =
158b8e80941Smrg      VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 2) | /* MSAA adds another input */
159b8e80941Smrg      VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8);
160b8e80941Smrg   cs->PS_TEMP_REGISTER_CONTROL_MSAA =
161b8e80941Smrg      VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 2));
162b8e80941Smrg
163b8e80941Smrg   uint32_t total_components = 0;
164b8e80941Smrg   DEFINE_ETNA_BITARRAY(num_components, ETNA_NUM_VARYINGS, 4) = {0};
165b8e80941Smrg   DEFINE_ETNA_BITARRAY(component_use, 4 * ETNA_NUM_VARYINGS, 2) = {0};
166b8e80941Smrg   for (int idx = 0; idx < link.num_varyings; ++idx) {
167b8e80941Smrg      const struct etna_varying *varying = &link.varyings[idx];
168b8e80941Smrg
169b8e80941Smrg      etna_bitarray_set(num_components, 4, idx, varying->num_components);
170b8e80941Smrg      for (int comp = 0; comp < varying->num_components; ++comp) {
171b8e80941Smrg         etna_bitarray_set(component_use, 2, total_components, varying->use[comp]);
172b8e80941Smrg         total_components += 1;
173b8e80941Smrg      }
174b8e80941Smrg   }
175b8e80941Smrg
176b8e80941Smrg   cs->GL_VARYING_TOTAL_COMPONENTS =
177b8e80941Smrg      VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(align(total_components, 2));
178b8e80941Smrg   cs->GL_VARYING_NUM_COMPONENTS = num_components[0];
179b8e80941Smrg   cs->GL_VARYING_COMPONENT_USE[0] = component_use[0];
180b8e80941Smrg   cs->GL_VARYING_COMPONENT_USE[1] = component_use[1];
181b8e80941Smrg
182b8e80941Smrg   cs->GL_HALTI5_SH_SPECIALS =
183b8e80941Smrg      0x7f7f0000 | /* unknown bits, probably other PS inputs */
184b8e80941Smrg      /* pointsize is last (see above) */
185b8e80941Smrg      VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT((vs->vs_pointsize_out_reg != -1) ?
186b8e80941Smrg                                              cs->VS_OUTPUT_COUNT * 4 : 0x00) |
187b8e80941Smrg      VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN((link.pcoord_varying_comp_ofs != -1) ?
188b8e80941Smrg                                              link.pcoord_varying_comp_ofs : 0x7f);
189b8e80941Smrg
190b8e80941Smrg   /* reference instruction memory */
191b8e80941Smrg   cs->vs_inst_mem_size = vs->code_size;
192b8e80941Smrg   cs->VS_INST_MEM = vs->code;
193b8e80941Smrg
194b8e80941Smrg   cs->ps_inst_mem_size = fs->code_size;
195b8e80941Smrg   cs->PS_INST_MEM = fs->code;
196b8e80941Smrg
197b8e80941Smrg   if (vs->needs_icache | fs->needs_icache) {
198b8e80941Smrg      /* If either of the shaders needs ICACHE, we use it for both. It is
199b8e80941Smrg       * either switched on or off for the entire shader processor.
200b8e80941Smrg       */
201b8e80941Smrg      if (!etna_icache_upload_shader(ctx, vs) ||
202b8e80941Smrg          !etna_icache_upload_shader(ctx, fs)) {
203b8e80941Smrg         assert(0);
204b8e80941Smrg         return false;
205b8e80941Smrg      }
206b8e80941Smrg
207b8e80941Smrg      cs->VS_INST_ADDR.bo = vs->bo;
208b8e80941Smrg      cs->VS_INST_ADDR.offset = 0;
209b8e80941Smrg      cs->VS_INST_ADDR.flags = ETNA_RELOC_READ;
210b8e80941Smrg      cs->PS_INST_ADDR.bo = fs->bo;
211b8e80941Smrg      cs->PS_INST_ADDR.offset = 0;
212b8e80941Smrg      cs->PS_INST_ADDR.flags = ETNA_RELOC_READ;
213b8e80941Smrg   } else {
214b8e80941Smrg      /* clear relocs */
215b8e80941Smrg      memset(&cs->VS_INST_ADDR, 0, sizeof(cs->VS_INST_ADDR));
216b8e80941Smrg      memset(&cs->PS_INST_ADDR, 0, sizeof(cs->PS_INST_ADDR));
217b8e80941Smrg   }
218b8e80941Smrg
219b8e80941Smrg   return true;
220b8e80941Smrg}
221b8e80941Smrg
222b8e80941Smrgbool
223b8e80941Smrgetna_shader_link(struct etna_context *ctx)
224b8e80941Smrg{
225b8e80941Smrg   if (!ctx->shader.vs || !ctx->shader.fs)
226b8e80941Smrg      return false;
227b8e80941Smrg
228b8e80941Smrg   /* re-link vs and fs if needed */
229b8e80941Smrg   return etna_link_shaders(ctx, &ctx->shader_state, ctx->shader.vs, ctx->shader.fs);
230b8e80941Smrg}
231b8e80941Smrg
232b8e80941Smrgstatic bool
233b8e80941Smrgetna_shader_update_vs_inputs(struct compiled_shader_state *cs,
234b8e80941Smrg                             const struct etna_shader_variant *vs,
235b8e80941Smrg                             const struct compiled_vertex_elements_state *ves)
236b8e80941Smrg{
237b8e80941Smrg   unsigned num_temps, cur_temp, num_vs_inputs;
238b8e80941Smrg
239b8e80941Smrg   if (!vs)
240b8e80941Smrg      return false;
241b8e80941Smrg
242b8e80941Smrg   /* Number of vertex elements determines number of VS inputs. Otherwise,
243b8e80941Smrg    * the GPU crashes. Allocate any unused vertex elements to VS temporary
244b8e80941Smrg    * registers. */
245b8e80941Smrg   num_vs_inputs = MAX2(ves->num_elements, vs->infile.num_reg);
246b8e80941Smrg   if (num_vs_inputs != ves->num_elements) {
247b8e80941Smrg      BUG("Number of elements %u does not match the number of VS inputs %zu",
248b8e80941Smrg          ves->num_elements, vs->infile.num_reg);
249b8e80941Smrg      return false;
250b8e80941Smrg   }
251b8e80941Smrg
252b8e80941Smrg   cur_temp = vs->num_temps;
253b8e80941Smrg   num_temps = num_vs_inputs - vs->infile.num_reg + cur_temp;
254b8e80941Smrg
255b8e80941Smrg   cs->VS_INPUT_COUNT = VIVS_VS_INPUT_COUNT_COUNT(num_vs_inputs) |
256b8e80941Smrg                        VIVS_VS_INPUT_COUNT_UNK8(vs->input_count_unk8);
257b8e80941Smrg   cs->VS_TEMP_REGISTER_CONTROL =
258b8e80941Smrg      VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS(num_temps);
259b8e80941Smrg
260b8e80941Smrg   /* vs inputs (attributes) */
261b8e80941Smrg   DEFINE_ETNA_BITARRAY(vs_input, 16, 8) = {0};
262b8e80941Smrg   for (int idx = 0; idx < num_vs_inputs; ++idx) {
263b8e80941Smrg      if (idx < vs->infile.num_reg)
264b8e80941Smrg         etna_bitarray_set(vs_input, 8, idx, vs->infile.reg[idx].reg);
265b8e80941Smrg      else
266b8e80941Smrg         etna_bitarray_set(vs_input, 8, idx, cur_temp++);
267b8e80941Smrg   }
268b8e80941Smrg
269b8e80941Smrg   for (int idx = 0; idx < ARRAY_SIZE(cs->VS_INPUT); ++idx)
270b8e80941Smrg      cs->VS_INPUT[idx] = vs_input[idx];
271b8e80941Smrg
272b8e80941Smrg   return true;
273b8e80941Smrg}
274b8e80941Smrg
275b8e80941Smrgstatic inline const char *
276b8e80941Smrgetna_shader_stage(struct etna_shader_variant *shader)
277b8e80941Smrg{
278b8e80941Smrg   switch (shader->processor) {
279b8e80941Smrg   case PIPE_SHADER_VERTEX:     return "VERT";
280b8e80941Smrg   case PIPE_SHADER_FRAGMENT:   return "FRAG";
281b8e80941Smrg   case PIPE_SHADER_COMPUTE:    return "CL";
282b8e80941Smrg   default:
283b8e80941Smrg      unreachable("invalid type");
284b8e80941Smrg      return NULL;
285b8e80941Smrg   }
286b8e80941Smrg}
287b8e80941Smrg
288b8e80941Smrgstatic void
289b8e80941Smrgdump_shader_info(struct etna_shader_variant *v, struct pipe_debug_callback *debug)
290b8e80941Smrg{
291b8e80941Smrg   if (!unlikely(etna_mesa_debug & ETNA_DBG_SHADERDB))
292b8e80941Smrg      return;
293b8e80941Smrg
294b8e80941Smrg   pipe_debug_message(debug, SHADER_INFO, "\n"
295b8e80941Smrg         "SHADER-DB: %s prog %d/%d: %u instructions %u temps\n"
296b8e80941Smrg         "SHADER-DB: %s prog %d/%d: %u immediates %u consts\n"
297b8e80941Smrg         "SHADER-DB: %s prog %d/%d: %u loops\n",
298b8e80941Smrg         etna_shader_stage(v),
299b8e80941Smrg         v->shader->id, v->id,
300b8e80941Smrg         v->code_size,
301b8e80941Smrg         v->num_temps,
302b8e80941Smrg         etna_shader_stage(v),
303b8e80941Smrg         v->shader->id, v->id,
304b8e80941Smrg         v->uniforms.imm_count,
305b8e80941Smrg         v->uniforms.const_count,
306b8e80941Smrg         etna_shader_stage(v),
307b8e80941Smrg         v->shader->id, v->id,
308b8e80941Smrg         v->num_loops);
309b8e80941Smrg}
310b8e80941Smrg
311b8e80941Smrgbool
312b8e80941Smrgetna_shader_update_vertex(struct etna_context *ctx)
313b8e80941Smrg{
314b8e80941Smrg   return etna_shader_update_vs_inputs(&ctx->shader_state, ctx->shader.vs,
315b8e80941Smrg                                       ctx->vertex_elements);
316b8e80941Smrg}
317b8e80941Smrg
318b8e80941Smrgstatic struct etna_shader_variant *
319b8e80941Smrgcreate_variant(struct etna_shader *shader, struct etna_shader_key key)
320b8e80941Smrg{
321b8e80941Smrg   struct etna_shader_variant *v = CALLOC_STRUCT(etna_shader_variant);
322b8e80941Smrg   int ret;
323b8e80941Smrg
324b8e80941Smrg   if (!v)
325b8e80941Smrg      return NULL;
326b8e80941Smrg
327b8e80941Smrg   v->shader = shader;
328b8e80941Smrg   v->key = key;
329b8e80941Smrg
330b8e80941Smrg   ret = etna_compile_shader(v);
331b8e80941Smrg   if (!ret) {
332b8e80941Smrg      debug_error("compile failed!");
333b8e80941Smrg      goto fail;
334b8e80941Smrg   }
335b8e80941Smrg
336b8e80941Smrg   v->id = ++shader->variant_count;
337b8e80941Smrg
338b8e80941Smrg   return v;
339b8e80941Smrg
340b8e80941Smrgfail:
341b8e80941Smrg   FREE(v);
342b8e80941Smrg   return NULL;
343b8e80941Smrg}
344b8e80941Smrg
345b8e80941Smrgstruct etna_shader_variant *
346b8e80941Smrgetna_shader_variant(struct etna_shader *shader, struct etna_shader_key key,
347b8e80941Smrg                   struct pipe_debug_callback *debug)
348b8e80941Smrg{
349b8e80941Smrg   struct etna_shader_variant *v;
350b8e80941Smrg
351b8e80941Smrg   for (v = shader->variants; v; v = v->next)
352b8e80941Smrg      if (etna_shader_key_equal(&key, &v->key))
353b8e80941Smrg         return v;
354b8e80941Smrg
355b8e80941Smrg   /* compile new variant if it doesn't exist already */
356b8e80941Smrg   v = create_variant(shader, key);
357b8e80941Smrg   if (v) {
358b8e80941Smrg      v->next = shader->variants;
359b8e80941Smrg      shader->variants = v;
360b8e80941Smrg      dump_shader_info(v, debug);
361b8e80941Smrg   }
362b8e80941Smrg
363b8e80941Smrg   return v;
364b8e80941Smrg}
365b8e80941Smrg
366b8e80941Smrgstatic void *
367b8e80941Smrgetna_create_shader_state(struct pipe_context *pctx,
368b8e80941Smrg                         const struct pipe_shader_state *pss)
369b8e80941Smrg{
370b8e80941Smrg   struct etna_context *ctx = etna_context(pctx);
371b8e80941Smrg   struct etna_shader *shader = CALLOC_STRUCT(etna_shader);
372b8e80941Smrg
373b8e80941Smrg   if (!shader)
374b8e80941Smrg      return NULL;
375b8e80941Smrg
376b8e80941Smrg   static uint32_t id;
377b8e80941Smrg   shader->id = id++;
378b8e80941Smrg   shader->specs = &ctx->specs;
379b8e80941Smrg   shader->tokens = tgsi_dup_tokens(pss->tokens);
380b8e80941Smrg
381b8e80941Smrg   if (etna_mesa_debug & ETNA_DBG_SHADERDB) {
382b8e80941Smrg      /* if shader-db run, create a standard variant immediately
383b8e80941Smrg       * (as otherwise nothing will trigger the shader to be
384b8e80941Smrg       * actually compiled).
385b8e80941Smrg       */
386b8e80941Smrg      struct etna_shader_key key = {};
387b8e80941Smrg      etna_shader_variant(shader, key, &ctx->debug);
388b8e80941Smrg   }
389b8e80941Smrg
390b8e80941Smrg   return shader;
391b8e80941Smrg}
392b8e80941Smrg
393b8e80941Smrgstatic void
394b8e80941Smrgetna_delete_shader_state(struct pipe_context *pctx, void *ss)
395b8e80941Smrg{
396b8e80941Smrg   struct etna_shader *shader = ss;
397b8e80941Smrg   struct etna_shader_variant *v, *t;
398b8e80941Smrg
399b8e80941Smrg   v = shader->variants;
400b8e80941Smrg   while (v) {
401b8e80941Smrg      t = v;
402b8e80941Smrg      v = v->next;
403b8e80941Smrg      if (t->bo)
404b8e80941Smrg         etna_bo_del(t->bo);
405b8e80941Smrg      etna_destroy_shader(t);
406b8e80941Smrg   }
407b8e80941Smrg
408b8e80941Smrg   FREE(shader->tokens);
409b8e80941Smrg   FREE(shader);
410b8e80941Smrg}
411b8e80941Smrg
412b8e80941Smrgstatic void
413b8e80941Smrgetna_bind_fs_state(struct pipe_context *pctx, void *hwcso)
414b8e80941Smrg{
415b8e80941Smrg   struct etna_context *ctx = etna_context(pctx);
416b8e80941Smrg
417b8e80941Smrg   ctx->shader.bind_fs = hwcso;
418b8e80941Smrg   ctx->dirty |= ETNA_DIRTY_SHADER;
419b8e80941Smrg}
420b8e80941Smrg
421b8e80941Smrgstatic void
422b8e80941Smrgetna_bind_vs_state(struct pipe_context *pctx, void *hwcso)
423b8e80941Smrg{
424b8e80941Smrg   struct etna_context *ctx = etna_context(pctx);
425b8e80941Smrg
426b8e80941Smrg   ctx->shader.bind_vs = hwcso;
427b8e80941Smrg   ctx->dirty |= ETNA_DIRTY_SHADER;
428b8e80941Smrg}
429b8e80941Smrg
430b8e80941Smrgvoid
431b8e80941Smrgetna_shader_init(struct pipe_context *pctx)
432b8e80941Smrg{
433b8e80941Smrg   pctx->create_fs_state = etna_create_shader_state;
434b8e80941Smrg   pctx->bind_fs_state = etna_bind_fs_state;
435b8e80941Smrg   pctx->delete_fs_state = etna_delete_shader_state;
436b8e80941Smrg   pctx->create_vs_state = etna_create_shader_state;
437b8e80941Smrg   pctx->bind_vs_state = etna_bind_vs_state;
438b8e80941Smrg   pctx->delete_vs_state = etna_delete_shader_state;
439b8e80941Smrg}
440