Merge remote-tracking branch 'origin/master' into vulkan
[mesa.git] / src / mesa / drivers / dri / i965 / brw_tcs.c
1 /*
2 * Copyright © 2014 Intel Corporation
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * \file brw_tcs.c
26 *
27 * Tessellation control shader state upload code.
28 */
29
30 #include "brw_context.h"
31 #include "brw_nir.h"
32 #include "brw_program.h"
33 #include "brw_shader.h"
34 #include "brw_state.h"
35 #include "program/prog_parameter.h"
36
37 static void
38 brw_tcs_debug_recompile(struct brw_context *brw,
39 struct gl_shader_program *shader_prog,
40 const struct brw_tcs_prog_key *key)
41 {
42 struct brw_cache_item *c = NULL;
43 const struct brw_tcs_prog_key *old_key = NULL;
44 bool found = false;
45
46 perf_debug("Recompiling tessellation control shader for program %d\n",
47 shader_prog->Name);
48
49 for (unsigned int i = 0; i < brw->cache.size; i++) {
50 for (c = brw->cache.items[i]; c; c = c->next) {
51 if (c->cache_id == BRW_CACHE_TCS_PROG) {
52 old_key = c->key;
53
54 if (old_key->program_string_id == key->program_string_id)
55 break;
56 }
57 }
58 if (c)
59 break;
60 }
61
62 if (!c) {
63 perf_debug(" Didn't find previous compile in the shader cache for "
64 "debug\n");
65 return;
66 }
67
68 found |= key_debug(brw, "input vertices", old_key->input_vertices,
69 key->input_vertices);
70 found |= key_debug(brw, "outputs written", old_key->outputs_written,
71 key->outputs_written);
72 found |= key_debug(brw, "patch outputs written", old_key->patch_outputs_written,
73 key->patch_outputs_written);
74 found |= key_debug(brw, "TES primitive mode", old_key->tes_primitive_mode,
75 key->tes_primitive_mode);
76 found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
77
78 if (!found) {
79 perf_debug(" Something else\n");
80 }
81 }
82
83 static bool
84 brw_codegen_tcs_prog(struct brw_context *brw,
85 struct gl_shader_program *shader_prog,
86 struct brw_tess_ctrl_program *tcp,
87 struct brw_tcs_prog_key *key)
88 {
89 struct gl_context *ctx = &brw->ctx;
90 const struct brw_compiler *compiler = brw->intelScreen->compiler;
91 struct brw_stage_state *stage_state = &brw->tcs.base;
92 nir_shader *nir;
93 struct brw_tcs_prog_data prog_data;
94 bool start_busy = false;
95 double start_time = 0;
96
97 if (tcp) {
98 nir = tcp->program.Base.nir;
99 } else {
100 /* Create a dummy nir_shader. We won't actually use NIR code to
101 * generate assembly (it's easier to generate assembly directly),
102 * but the whole compiler assumes one of these exists.
103 */
104 const nir_shader_compiler_options *options =
105 ctx->Const.ShaderCompilerOptions[MESA_SHADER_TESS_CTRL].NirOptions;
106 nir = nir_shader_create(NULL, MESA_SHADER_TESS_CTRL, options);
107 nir->num_uniforms = 2; /* both halves of the patch header */
108 nir->info.outputs_written = key->outputs_written;
109 nir->info.inputs_read = key->outputs_written;
110 nir->info.tcs.vertices_out = key->input_vertices;
111 nir->info.name = ralloc_strdup(nir, "passthrough");
112 }
113
114 memset(&prog_data, 0, sizeof(prog_data));
115
116 /* Allocate the references to the uniforms that will end up in the
117 * prog_data associated with the compiled program, and which will be freed
118 * by the state cache.
119 *
120 * Note: param_count needs to be num_uniform_components * 4, since we add
121 * padding around uniform values below vec4 size, so the worst case is that
122 * every uniform is a float which gets padded to the size of a vec4.
123 */
124 struct gl_shader *tcs = shader_prog ?
125 shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL] : NULL;
126 int param_count = nir->num_uniforms;
127 if (!compiler->scalar_stage[MESA_SHADER_TESS_CTRL])
128 param_count *= 4;
129
130 prog_data.base.base.param =
131 rzalloc_array(NULL, const gl_constant_value *, param_count);
132 prog_data.base.base.pull_param =
133 rzalloc_array(NULL, const gl_constant_value *, param_count);
134 prog_data.base.base.nr_params = param_count;
135
136 if (tcs) {
137 prog_data.base.base.image_param =
138 rzalloc_array(NULL, struct brw_image_param, tcs->NumImages);
139 prog_data.base.base.nr_image_params = tcs->NumImages;
140
141 brw_nir_setup_glsl_uniforms(nir, shader_prog, &tcp->program.Base,
142 &prog_data.base.base, false);
143 } else {
144 /* Upload the Patch URB Header as the first two uniforms.
145 * Do the annoying scrambling so the shader doesn't have to.
146 */
147 const float **param = (const float **) prog_data.base.base.param;
148 static float zero = 0.0f;
149 for (int i = 0; i < 4; i++) {
150 param[7 - i] = &ctx->TessCtrlProgram.patch_default_outer_level[i];
151 }
152
153 if (key->tes_primitive_mode == GL_QUADS) {
154 param[3] = &ctx->TessCtrlProgram.patch_default_inner_level[0];
155 param[2] = &ctx->TessCtrlProgram.patch_default_inner_level[1];
156 param[1] = &zero;
157 param[0] = &zero;
158 } else if (key->tes_primitive_mode == GL_TRIANGLES) {
159 param[4] = &ctx->TessCtrlProgram.patch_default_inner_level[0];
160 for (int i = 0; i < 4; i++)
161 param[i] = &zero;
162 }
163 }
164
165 if (unlikely(INTEL_DEBUG & DEBUG_TCS) && tcs)
166 brw_dump_ir("tessellation control", shader_prog, tcs, NULL);
167
168 int st_index = -1;
169 if (unlikely(INTEL_DEBUG & DEBUG_SHADER_TIME))
170 st_index = brw_get_shader_time_index(brw, shader_prog, NULL, ST_TCS);
171
172 if (unlikely(brw->perf_debug)) {
173 start_busy = brw->batch.last_bo && drm_intel_bo_busy(brw->batch.last_bo);
174 start_time = get_time();
175 }
176
177 void *mem_ctx = ralloc_context(NULL);
178 unsigned program_size;
179 char *error_str;
180 const unsigned *program =
181 brw_compile_tcs(compiler, brw, mem_ctx, key, &prog_data, nir, st_index,
182 &program_size, &error_str);
183 if (program == NULL) {
184 if (shader_prog) {
185 shader_prog->LinkStatus = false;
186 ralloc_strcat(&shader_prog->InfoLog, error_str);
187 } else {
188 ralloc_free(nir);
189 }
190
191 _mesa_problem(NULL, "Failed to compile tessellation control shader: "
192 "%s\n", error_str);
193
194 ralloc_free(mem_ctx);
195 return false;
196 }
197
198 if (unlikely(brw->perf_debug)) {
199 struct brw_shader *btcs = (struct brw_shader *) tcs;
200 if (btcs->compiled_once) {
201 brw_tcs_debug_recompile(brw, shader_prog, key);
202 }
203 if (start_busy && !drm_intel_bo_busy(brw->batch.last_bo)) {
204 perf_debug("TCS compile took %.03f ms and stalled the GPU\n",
205 (get_time() - start_time) * 1000);
206 }
207 btcs->compiled_once = true;
208 }
209
210 /* Scratch space is used for register spilling */
211 if (prog_data.base.base.total_scratch) {
212 brw_get_scratch_bo(brw, &stage_state->scratch_bo,
213 prog_data.base.base.total_scratch *
214 brw->max_hs_threads);
215 }
216
217 brw_upload_cache(&brw->cache, BRW_CACHE_TCS_PROG,
218 key, sizeof(*key),
219 program, program_size,
220 &prog_data, sizeof(prog_data),
221 &stage_state->prog_offset, &brw->tcs.prog_data);
222 ralloc_free(mem_ctx);
223 if (!tcs)
224 ralloc_free(nir);
225
226 return true;
227 }
228
229
230 void
231 brw_upload_tcs_prog(struct brw_context *brw,
232 uint64_t per_vertex_slots,
233 uint32_t per_patch_slots)
234 {
235 struct gl_context *ctx = &brw->ctx;
236 struct gl_shader_program **current = ctx->_Shader->CurrentProgram;
237 struct brw_stage_state *stage_state = &brw->tcs.base;
238 struct brw_tcs_prog_key key;
239 /* BRW_NEW_TESS_PROGRAMS */
240 struct brw_tess_ctrl_program *tcp =
241 (struct brw_tess_ctrl_program *) brw->tess_ctrl_program;
242 struct brw_tess_eval_program *tep =
243 (struct brw_tess_eval_program *) brw->tess_eval_program;
244 assert(tep);
245
246 if (!brw_state_dirty(brw,
247 _NEW_TEXTURE,
248 BRW_NEW_PATCH_PRIMITIVE |
249 BRW_NEW_TESS_PROGRAMS))
250 return;
251
252 struct gl_program *prog = &tcp->program.Base;
253
254 memset(&key, 0, sizeof(key));
255
256 key.input_vertices = ctx->TessCtrlProgram.patch_vertices;
257 key.outputs_written = per_vertex_slots;
258 key.patch_outputs_written = per_patch_slots;
259
260 /* We need to specialize our code generation for tessellation levels
261 * based on the domain the DS is expecting to tessellate.
262 */
263 key.tes_primitive_mode = tep->program.PrimitiveMode;
264
265 if (tcp) {
266 key.program_string_id = tcp->id;
267
268 /* _NEW_TEXTURE */
269 brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
270 &key.tex);
271 } else {
272 key.outputs_written = tep->program.Base.InputsRead;
273 }
274
275
276 if (!brw_search_cache(&brw->cache, BRW_CACHE_TCS_PROG,
277 &key, sizeof(key),
278 &stage_state->prog_offset, &brw->tcs.prog_data)) {
279 bool success = brw_codegen_tcs_prog(brw, current[MESA_SHADER_TESS_CTRL],
280 tcp, &key);
281 assert(success);
282 (void)success;
283 }
284 brw->tcs.base.prog_data = &brw->tcs.prog_data->base.base;
285 }
286
287
288 bool
289 brw_tcs_precompile(struct gl_context *ctx,
290 struct gl_shader_program *shader_prog,
291 struct gl_program *prog)
292 {
293 struct brw_context *brw = brw_context(ctx);
294 struct brw_tcs_prog_key key;
295 uint32_t old_prog_offset = brw->tcs.base.prog_offset;
296 struct brw_tcs_prog_data *old_prog_data = brw->tcs.prog_data;
297 bool success;
298
299 struct gl_tess_ctrl_program *tcp = (struct gl_tess_ctrl_program *)prog;
300 struct brw_tess_ctrl_program *btcp = brw_tess_ctrl_program(tcp);
301
302 memset(&key, 0, sizeof(key));
303
304 key.program_string_id = btcp->id;
305 brw_setup_tex_for_precompile(brw, &key.tex, prog);
306
307 /* Guess that the input and output patches have the same dimensionality. */
308 key.input_vertices = shader_prog->TessCtrl.VerticesOut;
309
310 key.tes_primitive_mode =
311 shader_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] ?
312 shader_prog->TessEval.PrimitiveMode : GL_TRIANGLES;
313
314 key.outputs_written = prog->OutputsWritten;
315 key.patch_outputs_written = prog->PatchOutputsWritten;
316
317 success = brw_codegen_tcs_prog(brw, shader_prog, btcp, &key);
318
319 brw->tcs.base.prog_offset = old_prog_offset;
320 brw->tcs.prog_data = old_prog_data;
321
322 return success;
323 }