dst[0]->cat6.type = TYPE_U32;
__ssa_dst(dst[0]);
break;
+ case nir_intrinsic_load_tess_level_outer_default:
+ for (int i = 0; i < dest_components; i++) {
+ dst[i] = create_driver_param(ctx, IR3_DP_HS_DEFAULT_OUTER_LEVEL_X + i);
+ }
+ break;
+ case nir_intrinsic_load_tess_level_inner_default:
+ for (int i = 0; i < dest_components; i++) {
+ dst[i] = create_driver_param(ctx, IR3_DP_HS_DEFAULT_INNER_LEVEL_X + i);
+ }
+ break;
case nir_intrinsic_discard_if:
case nir_intrinsic_discard:
case nir_intrinsic_demote:
progress = true;
break;
case MESA_SHADER_TESS_CTRL:
+ NIR_PASS_V(s, nir_lower_io_to_scalar,
+ nir_var_shader_in | nir_var_shader_out);
NIR_PASS_V(s, ir3_nir_lower_tess_ctrl, so, so->key.tessellation);
NIR_PASS_V(s, ir3_nir_lower_to_explicit_input, so);
progress = true;
layout->num_driver_params =
MAX2(layout->num_driver_params, IR3_DP_DRAWID + 1);
break;
+ case nir_intrinsic_load_tess_level_outer_default:
+ layout->num_driver_params = MAX2(layout->num_driver_params,
+ IR3_DP_HS_DEFAULT_OUTER_LEVEL_W + 1);
+ break;
+ case nir_intrinsic_load_tess_level_inner_default:
+ layout->num_driver_params = MAX2(layout->num_driver_params,
+ IR3_DP_HS_DEFAULT_INNER_LEVEL_Y + 1);
+ break;
default:
break;
}
return v;
}
+struct ir3_shader *
+ir3_shader_passthrough_tcs(struct ir3_shader *vs, unsigned patch_vertices)
+{
+ assert(vs->type == MESA_SHADER_VERTEX);
+ assert(patch_vertices > 0);
+ assert(patch_vertices <= 32);
+
+ unsigned n = patch_vertices - 1;
+ if (!vs->vs.passthrough_tcs[n]) {
+ const nir_shader_compiler_options *options =
+ ir3_get_compiler_options(vs->compiler);
+ nir_shader *tcs =
+ nir_create_passthrough_tcs(options, vs->nir, patch_vertices);
+
+ /* Technically it is an internal shader but it is confusing to
+ * not have it show up in debug output
+ */
+ tcs->info.internal = false;
+
+ nir_assign_io_var_locations(tcs, nir_var_shader_in,
+ &tcs->num_inputs,
+ tcs->info.stage);
+
+ nir_assign_io_var_locations(tcs, nir_var_shader_out,
+ &tcs->num_outputs,
+ tcs->info.stage);
+
+ NIR_PASS_V(tcs, nir_lower_system_values);
+
+ nir_shader_gather_info(tcs, nir_shader_get_entrypoint(tcs));
+
+ ir3_finalize_nir(vs->compiler, tcs);
+
+ struct ir3_shader_options ir3_options = {};
+
+ vs->vs.passthrough_tcs[n] =
+ ir3_shader_from_nir(vs->compiler, tcs, &ir3_options, NULL);
+
+ vs->vs.passthrough_tcs_compiled |= BITFIELD_BIT(n);
+ }
+
+ return vs->vs.passthrough_tcs[n];
+}
+
void
ir3_shader_destroy(struct ir3_shader *shader)
{
+ if (shader->type == MESA_SHADER_VERTEX) {
+ u_foreach_bit (b, shader->vs.passthrough_tcs_compiled) {
+ ir3_shader_destroy(shader->vs.passthrough_tcs[b]);
+ }
+ }
ralloc_free(shader->nir);
mtx_destroy(&shader->variants_lock);
ralloc_free(shader);
IR3_DP_UCP7_W = 35,
IR3_DP_VS_COUNT = 36, /* must be aligned to vec4 */
+ /* TCS driver params: */
+ IR3_DP_HS_DEFAULT_OUTER_LEVEL_X = 0,
+ IR3_DP_HS_DEFAULT_OUTER_LEVEL_Y = 1,
+ IR3_DP_HS_DEFAULT_OUTER_LEVEL_Z = 2,
+ IR3_DP_HS_DEFAULT_OUTER_LEVEL_W = 3,
+ IR3_DP_HS_DEFAULT_INNER_LEVEL_X = 4,
+ IR3_DP_HS_DEFAULT_INNER_LEVEL_Y = 5,
+ IR3_DP_HS_COUNT = 8, /* must be aligned to vec4 */
+
/* fragment shader driver params: */
IR3_DP_FS_SUBGROUP_SIZE = 0,
};
unsigned req_input_mem; /* in dwords */
unsigned req_local_mem;
} cs;
+ /* For vertex shaders: */
+ struct {
+ /* If we need to generate a passthrough TCS, it will be a function of
+ * (a) the VS and (b) the # of patch_vertices (max 32), so cache them
+ * in the VS keyed by # of patch_vertices-1.
+ */
+ unsigned passthrough_tcs_compiled;
+ struct ir3_shader *passthrough_tcs[32];
+ } vs;
};
struct ir3_shader_variant *variants;
struct ir3_stream_output_info *stream_output);
uint32_t ir3_trim_constlen(struct ir3_shader_variant **variants,
const struct ir3_compiler *compiler);
+struct ir3_shader *
+ir3_shader_passthrough_tcs(struct ir3_shader *vs, unsigned patch_vertices);
void ir3_shader_destroy(struct ir3_shader *shader);
void ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin, FILE *out);
uint64_t ir3_shader_outputs(const struct ir3_shader *so);