freedreno/ir3: Pass stream output info to ir3_shader_from_nir
[mesa.git] / src / gallium / drivers / freedreno / ir3 / ir3_gallium.c
1 /*
2 * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
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, sublicense,
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 next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * 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 NONINFRINGEMENT. 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 FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Rob Clark <robclark@freedesktop.org>
25 */
26
27 #include "pipe/p_state.h"
28 #include "pipe/p_screen.h"
29 #include "util/u_string.h"
30 #include "util/u_memory.h"
31 #include "util/u_inlines.h"
32 #include "util/format/u_format.h"
33 #include "tgsi/tgsi_dump.h"
34 #include "tgsi/tgsi_parse.h"
35
36 #include "nir/tgsi_to_nir.h"
37
38 #include "freedreno_context.h"
39 #include "freedreno_util.h"
40
41 #include "ir3/ir3_shader.h"
42 #include "ir3/ir3_gallium.h"
43 #include "ir3/ir3_compiler.h"
44 #include "ir3/ir3_nir.h"
45
46 static void
47 dump_shader_info(struct ir3_shader_variant *v, bool binning_pass,
48 struct pipe_debug_callback *debug)
49 {
50 if (!unlikely(fd_mesa_debug & FD_DBG_SHADERDB))
51 return;
52
53 pipe_debug_message(debug, SHADER_INFO,
54 "%s shader: %u inst, %u nops, %u non-nops, %u mov, %u cov, "
55 "%u dwords, %u last-baryf, %u half, %u full, %u constlen, "
56 "%u sstall, %u (ss), %u (sy), %d max_sun, %d loops\n",
57 ir3_shader_stage(v),
58 v->info.instrs_count,
59 v->info.nops_count,
60 v->info.instrs_count - v->info.nops_count,
61 v->info.mov_count,
62 v->info.cov_count,
63 v->info.sizedwords,
64 v->info.last_baryf,
65 v->info.max_half_reg + 1,
66 v->info.max_reg + 1,
67 v->constlen,
68 v->info.sstall,
69 v->info.ss, v->info.sy,
70 v->max_sun, v->loops);
71 }
72
73 struct ir3_shader_variant *
74 ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key,
75 bool binning_pass, struct pipe_debug_callback *debug)
76 {
77 struct ir3_shader_variant *v;
78 bool created = false;
79
80 /* some shader key values only apply to vertex or frag shader,
81 * so normalize the key to avoid constructing multiple identical
82 * variants:
83 */
84 ir3_normalize_key(&key, shader->type);
85
86 v = ir3_shader_get_variant(shader, &key, binning_pass, &created);
87
88 if (created) {
89 dump_shader_info(v, binning_pass, debug);
90 }
91
92 return v;
93 }
94
95 static void
96 copy_stream_out(struct ir3_stream_output_info *i,
97 const struct pipe_stream_output_info *p)
98 {
99 STATIC_ASSERT(ARRAY_SIZE(i->stride) == ARRAY_SIZE(p->stride));
100 STATIC_ASSERT(ARRAY_SIZE(i->output) == ARRAY_SIZE(p->output));
101
102 i->num_outputs = p->num_outputs;
103 for (int n = 0; n < ARRAY_SIZE(i->stride); n++)
104 i->stride[n] = p->stride[n];
105
106 for (int n = 0; n < ARRAY_SIZE(i->output); n++) {
107 i->output[n].register_index = p->output[n].register_index;
108 i->output[n].start_component = p->output[n].start_component;
109 i->output[n].num_components = p->output[n].num_components;
110 i->output[n].output_buffer = p->output[n].output_buffer;
111 i->output[n].dst_offset = p->output[n].dst_offset;
112 i->output[n].stream = p->output[n].stream;
113 }
114 }
115
116 struct ir3_shader *
117 ir3_shader_create(struct ir3_compiler *compiler,
118 const struct pipe_shader_state *cso,
119 struct pipe_debug_callback *debug,
120 struct pipe_screen *screen)
121 {
122 nir_shader *nir;
123 if (cso->type == PIPE_SHADER_IR_NIR) {
124 /* we take ownership of the reference: */
125 nir = cso->ir.nir;
126 } else {
127 debug_assert(cso->type == PIPE_SHADER_IR_TGSI);
128 if (ir3_shader_debug & IR3_DBG_DISASM) {
129 tgsi_dump(cso->tokens, 0);
130 }
131 nir = tgsi_to_nir(cso->tokens, screen);
132 }
133
134 struct ir3_stream_output_info stream_output;
135 copy_stream_out(&stream_output, &cso->stream_output);
136
137 struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir, &stream_output);
138
139 if (fd_mesa_debug & FD_DBG_SHADERDB) {
140 /* if shader-db run, create a standard variant immediately
141 * (as otherwise nothing will trigger the shader to be
142 * actually compiled)
143 */
144 static struct ir3_shader_key key; /* static is implicitly zeroed */
145 ir3_shader_variant(shader, key, false, debug);
146
147 if (nir->info.stage != MESA_SHADER_FRAGMENT)
148 ir3_shader_variant(shader, key, true, debug);
149 }
150
151 return shader;
152 }
153
154 /* a bit annoying that compute-shader and normal shader state objects
155 * aren't a bit more aligned.
156 */
157 struct ir3_shader *
158 ir3_shader_create_compute(struct ir3_compiler *compiler,
159 const struct pipe_compute_state *cso,
160 struct pipe_debug_callback *debug,
161 struct pipe_screen *screen)
162 {
163 nir_shader *nir;
164 if (cso->ir_type == PIPE_SHADER_IR_NIR) {
165 /* we take ownership of the reference: */
166 nir = (nir_shader *)cso->prog;
167 } else {
168 debug_assert(cso->ir_type == PIPE_SHADER_IR_TGSI);
169 if (ir3_shader_debug & IR3_DBG_DISASM) {
170 tgsi_dump(cso->prog, 0);
171 }
172 nir = tgsi_to_nir(cso->prog, screen);
173 }
174
175 struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir, NULL);
176
177 if (fd_mesa_debug & FD_DBG_SHADERDB) {
178 /* if shader-db run, create a standard variant immediately
179 * (as otherwise nothing will trigger the shader to be
180 * actually compiled)
181 */
182 static struct ir3_shader_key key; /* static is implicitly zeroed */
183 ir3_shader_variant(shader, key, false, debug);
184 }
185
186 return shader;
187 }
188
189 static void *
190 ir3_shader_state_create(struct pipe_context *pctx, const struct pipe_shader_state *cso)
191 {
192 struct fd_context *ctx = fd_context(pctx);
193 struct ir3_compiler *compiler = ctx->screen->compiler;
194 return ir3_shader_create(compiler, cso, &ctx->debug, pctx->screen);
195 }
196
197 static void
198 ir3_shader_state_delete(struct pipe_context *pctx, void *hwcso)
199 {
200 struct ir3_shader *so = hwcso;
201 ir3_shader_destroy(so);
202 }
203
204 void
205 ir3_prog_init(struct pipe_context *pctx)
206 {
207 pctx->create_vs_state = ir3_shader_state_create;
208 pctx->delete_vs_state = ir3_shader_state_delete;
209
210 pctx->create_tcs_state = ir3_shader_state_create;
211 pctx->delete_tcs_state = ir3_shader_state_delete;
212
213 pctx->create_tes_state = ir3_shader_state_create;
214 pctx->delete_tes_state = ir3_shader_state_delete;
215
216 pctx->create_gs_state = ir3_shader_state_create;
217 pctx->delete_gs_state = ir3_shader_state_delete;
218
219 pctx->create_fs_state = ir3_shader_state_create;
220 pctx->delete_fs_state = ir3_shader_state_delete;
221 }