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