unsigned input_vertices;
+ /** A bitfield of per-patch outputs written. */
+ uint32_t patch_outputs_written;
+
/** A bitfield of per-vertex outputs written. */
uint64_t outputs_written;
{
unsigned program_string_id;
+ /** A bitfield of per-patch inputs read. */
+ uint32_t patch_inputs_read;
+
+ /** A bitfield of per-vertex inputs read. */
+ uint64_t inputs_read;
+
struct brw_sampler_prog_key_data tex;
};
/* First, lower the GLSL IR or Mesa IR to NIR */
if (shader_prog) {
nir = glsl_to_nir(shader_prog, stage, options);
-
- if (nir->stage == MESA_SHADER_TESS_EVAL &&
- shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]) {
- const struct gl_program *tcs =
- shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program;
- /* Work around the TCS having bonus outputs used as shared memory
- * segments, which makes OutputsWritten not match InputsRead
- */
- nir->info.inputs_read = tcs->OutputsWritten;
- nir->info.patch_inputs_read = tcs->PatchOutputsWritten;
- }
} else {
nir = prog_to_nir(prog, options);
OPT_V(nir_convert_to_ssa); /* turn registers into SSA */
brw_dump_ir(const char *stage, struct gl_shader_program *shader_prog,
struct gl_shader *shader, struct gl_program *prog);
-void brw_upload_tcs_prog(struct brw_context *brw);
-void brw_upload_tes_prog(struct brw_context *brw);
+void brw_upload_tcs_prog(struct brw_context *brw,
+ uint64_t per_vertex_slots, uint32_t per_patch_slots);
+void brw_upload_tes_prog(struct brw_context *brw,
+ uint64_t per_vertex_slots, uint32_t per_patch_slots);
#ifdef __cplusplus
} /* extern "C" */
nir_shader *nir = nir_shader_clone(mem_ctx, src_shader);
nir = brw_nir_apply_sampler_key(nir, devinfo, &key->tex, is_scalar);
+ nir->info.inputs_read = key->inputs_read;
+ nir->info.patch_inputs_read = key->patch_inputs_read;
nir = brw_nir_lower_io(nir, compiler->devinfo, is_scalar);
nir = brw_postprocess_nir(nir, compiler->devinfo, is_scalar);
}
}
+static inline void
+brw_upload_tess_programs(struct brw_context *brw)
+{
+ if (brw->tess_eval_program) {
+ uint64_t per_vertex_slots = brw->tess_eval_program->Base.InputsRead;
+ uint32_t per_patch_slots =
+ brw->tess_eval_program->Base.PatchInputsRead;
+
+ /* The TCS may have additional outputs which aren't read by the
+ * TES (possibly for cross-thread communication). These need to
+ * be stored in the Patch URB Entry as well.
+ */
+ if (brw->tess_ctrl_program) {
+ per_vertex_slots |= brw->tess_ctrl_program->Base.OutputsWritten;
+ per_patch_slots |=
+ brw->tess_ctrl_program->Base.PatchOutputsWritten;
+ }
+
+ brw_upload_tcs_prog(brw, per_vertex_slots, per_patch_slots);
+ brw_upload_tes_prog(brw, per_vertex_slots, per_patch_slots);
+ } else {
+ brw->tcs.prog_data = NULL;
+ brw->tcs.base.prog_data = NULL;
+ brw->tes.prog_data = NULL;
+ brw->tes.base.prog_data = NULL;
+ }
+}
+
static inline void
brw_upload_programs(struct brw_context *brw,
enum brw_pipeline pipeline)
{
if (pipeline == BRW_RENDER_PIPELINE) {
brw_upload_vs_prog(brw);
- if (brw->tess_eval_program) {
- brw_upload_tcs_prog(brw);
- brw_upload_tes_prog(brw);
- } else {
- brw->tcs.prog_data = NULL;
- brw->tcs.base.prog_data = NULL;
- brw->tes.prog_data = NULL;
- brw->tes.base.prog_data = NULL;
- }
+ brw_upload_tess_programs(brw);
if (brw->gen < 6)
brw_upload_ff_gs_prog(brw);
found |= key_debug(brw, "input vertices", old_key->input_vertices,
key->input_vertices);
+ found |= key_debug(brw, "outputs written", old_key->outputs_written,
+ key->outputs_written);
+ found |= key_debug(brw, "patch outputs written", old_key->patch_outputs_written,
+ key->patch_outputs_written);
found |= key_debug(brw, "TES primitive mode", old_key->tes_primitive_mode,
key->tes_primitive_mode);
found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
void
-brw_upload_tcs_prog(struct brw_context *brw)
+brw_upload_tcs_prog(struct brw_context *brw,
+ uint64_t per_vertex_slots,
+ uint32_t per_patch_slots)
{
struct gl_context *ctx = &brw->ctx;
struct gl_shader_program **current = ctx->_Shader->CurrentProgram;
memset(&key, 0, sizeof(key));
key.input_vertices = ctx->TessCtrlProgram.patch_vertices;
+ key.outputs_written = per_vertex_slots;
+ key.patch_outputs_written = per_patch_slots;
/* We need to specialize our code generation for tessellation levels
* based on the domain the DS is expecting to tessellate.
key.tes_primitive_mode = GL_TRIANGLES;
+ key.outputs_written = prog->OutputsWritten;
+ key.patch_outputs_written = prog->PatchOutputsWritten;
+
success = brw_codegen_tcs_prog(brw, shader_prog, btcp, &key);
brw->tcs.base.prog_offset = old_prog_offset;
}
found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
+ found |= key_debug(brw, "inputs read", old_key->inputs_read,
+ key->inputs_read);
+ found |= key_debug(brw, "patch inputs read", old_key->patch_inputs_read,
+ key->patch_inputs_read);
if (!found) {
perf_debug(" Something else\n");
void
-brw_upload_tes_prog(struct brw_context *brw)
+brw_upload_tes_prog(struct brw_context *brw,
+ uint64_t per_vertex_slots,
+ uint32_t per_patch_slots)
{
struct gl_context *ctx = &brw->ctx;
struct gl_shader_program **current = ctx->_Shader->CurrentProgram;
key.program_string_id = tep->id;
+ /* Ignore gl_TessLevelInner/Outer - we treat them as system values,
+ * not inputs, and they're always present in the URB entry regardless
+ * of whether or not we read them.
+ */
+ key.inputs_read = per_vertex_slots &
+ ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
+ key.patch_inputs_read = per_patch_slots;
+
/* _NEW_TEXTURE */
brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
&key.tex);
memset(&key, 0, sizeof(key));
key.program_string_id = btep->id;
+ key.inputs_read = prog->InputsRead;
+ key.patch_inputs_read = prog->PatchInputsRead;
+
+ if (shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]) {
+ struct gl_program *tcp =
+ shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program;
+ key.inputs_read |= tcp->OutputsWritten;
+ key.patch_inputs_read |= tcp->PatchOutputsWritten;
+ }
+
+ /* Ignore gl_TessLevelInner/Outer - they're system values. */
+ key.inputs_read &= ~(VARYING_BIT_TESS_LEVEL_INNER |
+ VARYING_BIT_TESS_LEVEL_OUTER);
+
brw_setup_tex_for_precompile(brw, &key.tex, prog);
success = brw_codegen_tes_prog(brw, shader_prog, btep, &key);
nir_shader *nir = nir_shader_clone(mem_ctx, src_shader);
nir = brw_nir_apply_sampler_key(nir, devinfo, &key->tex, is_scalar);
+ nir->info.outputs_written = key->outputs_written;
+ nir->info.patch_outputs_written = key->patch_outputs_written;
nir = brw_nir_lower_io(nir, compiler->devinfo, is_scalar);
nir = brw_postprocess_nir(nir, compiler->devinfo, is_scalar);