{
struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
const struct brw_compiler *compiler = screen->compiler;
+ const struct nir_shader_compiler_options *options =
+ compiler->glsl_compiler_options[MESA_SHADER_TESS_CTRL].NirOptions;
const struct gen_device_info *devinfo = &screen->devinfo;
void *mem_ctx = ralloc_context(NULL);
struct brw_tcs_prog_data *tcs_prog_data =
struct brw_vue_prog_data *vue_prog_data = &tcs_prog_data->base;
struct brw_stage_prog_data *prog_data = &vue_prog_data->base;
- nir_shader *nir = ish->nir;
+ nir_shader *nir;
- assign_common_binding_table_offsets(devinfo, nir, prog_data, 0);
+ if (ish) {
+ nir = ish->nir;
- iris_setup_uniforms(compiler, mem_ctx, nir, prog_data);
+ assign_common_binding_table_offsets(devinfo, nir, prog_data, 0);
+ iris_setup_uniforms(compiler, mem_ctx, nir, prog_data);
+ } else {
+ nir = brw_nir_create_passthrough_tcs(mem_ctx, compiler, options, key);
+
+ /* Reserve space for passing the default tess levels as constants. */
+ prog_data->param = rzalloc_array(mem_ctx, uint32_t, 8);
+ prog_data->nr_params = 8;
+ prog_data->ubo_ranges[0].length = 1;
+ }
char *error_str = NULL;
const unsigned *program =
{
struct iris_uncompiled_shader *tcs =
ice->shaders.uncompiled[MESA_SHADER_TESS_CTRL];
- struct iris_uncompiled_shader *tes =
- ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL];
-
- assert(!(tes && !tcs));
-
- if (!tcs) {
- iris_unbind_shader(ice, IRIS_CACHE_TCS);
- return;
- }
const struct shader_info *tes_info =
iris_get_shader_info(ice, MESA_SHADER_TESS_EVAL);
struct brw_tcs_prog_key key = {
- .program_string_id = tcs->program_id,
+ .program_string_id = tcs ? tcs->program_id : get_new_program_id((void *)ice->ctx.screen),
.tes_primitive_mode = tes_info->tess.primitive_mode,
+ .input_vertices = ice->state.vertices_per_patch,
};
get_unified_tess_slots(ice, &key.outputs_written,
&key.patch_outputs_written);
struct iris_uncompiled_shader *ish =
ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL];
- if (!ish) {
- iris_unbind_shader(ice, IRIS_CACHE_TES);
- return;
- }
-
struct brw_tes_prog_key key = { .program_string_id = ish->program_id };
get_unified_tess_slots(ice, &key.inputs_read, &key.patch_inputs_read);
ice->vtbl.populate_tes_key(ice, &key);
old_prog_datas[i] = get_vue_prog_data(ice, i);
}
+ if (dirty & (IRIS_DIRTY_UNCOMPILED_TCS | IRIS_DIRTY_UNCOMPILED_TES)) {
+ struct iris_uncompiled_shader *tes =
+ ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL];
+ if (tes) {
+ iris_update_compiled_tcs(ice);
+ iris_update_compiled_tes(ice);
+ } else {
+ iris_unbind_shader(ice, IRIS_CACHE_TCS);
+ iris_unbind_shader(ice, IRIS_CACHE_TES);
+ }
+ }
+
if (dirty & IRIS_DIRTY_UNCOMPILED_VS)
iris_update_compiled_vs(ice);
- if (dirty & IRIS_DIRTY_UNCOMPILED_TCS)
- iris_update_compiled_tcs(ice);
- if (dirty & IRIS_DIRTY_UNCOMPILED_TES)
- iris_update_compiled_tes(ice);
if (dirty & IRIS_DIRTY_UNCOMPILED_GS)
iris_update_compiled_gs(ice);
ice->state.dirty |= (IRIS_DIRTY_BINDINGS_VS << stage);
}
+/**
+ * The pipe->set_tess_state() driver hook.
+ */
+static void
+iris_set_tess_state(struct pipe_context *ctx,
+ const float default_outer_level[4],
+ const float default_inner_level[2])
+{
+ struct iris_context *ice = (struct iris_context *) ctx;
+
+ memcpy(&ice->state.default_outer_level[0], &default_outer_level[0], 4 * sizeof(float));
+ memcpy(&ice->state.default_inner_level[0], &default_inner_level[0], 2 * sizeof(float));
+
+ ice->state.dirty |= IRIS_DIRTY_CONSTANTS_TCS;
+}
+
static void
iris_surface_destroy(struct pipe_context *ctx, struct pipe_surface *p_surf)
{
if (!shader)
return;
- const struct shader_info *info = iris_get_shader_info(ice, stage);
struct iris_shader_state *shs = &ice->state.shaders[stage];
uint32_t binder_addr = binder->bo->gtt_offset;
uint32_t *bt_map = binder->map + binder->bt_offset[stage];
int s = 0;
+ const struct shader_info *info = iris_get_shader_info(ice, stage);
+ if (!info) {
+ /* TCS passthrough doesn't need a binding table. */
+ assert(stage == MESA_SHADER_TESS_CTRL);
+ return;
+ }
+
if (stage == MESA_SHADER_FRAGMENT) {
struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
/* Note that cso_fb->nr_cbufs == fs_key->nr_color_regions. */
}
}
+ /* Upload constants for TCS passthrough. */
+ if ((dirty & IRIS_DIRTY_CONSTANTS_TCS) &&
+ ice->shaders.prog[MESA_SHADER_TESS_CTRL] &&
+ !ice->shaders.uncompiled[MESA_SHADER_TESS_CTRL]) {
+ struct iris_compiled_shader *tes_shader = ice->shaders.prog[MESA_SHADER_TESS_EVAL];
+ assert(tes_shader);
+
+ /* Passthrough always copies 2 vec4s, so when uploading data we ensure
+ * it is in the right layout for TES.
+ */
+ float hdr[8] = {};
+ struct brw_tes_prog_data *tes_prog_data = (void *) tes_shader->prog_data;
+ switch (tes_prog_data->domain) {
+ case BRW_TESS_DOMAIN_QUAD:
+ for (int i = 0; i < 4; i++)
+ hdr[7 - i] = ice->state.default_outer_level[i];
+ hdr[3] = ice->state.default_inner_level[0];
+ hdr[2] = ice->state.default_inner_level[1];
+ break;
+ case BRW_TESS_DOMAIN_TRI:
+ for (int i = 0; i < 3; i++)
+ hdr[7 - i] = ice->state.default_outer_level[i];
+ hdr[4] = ice->state.default_inner_level[0];
+ break;
+ case BRW_TESS_DOMAIN_ISOLINE:
+ hdr[7] = ice->state.default_outer_level[1];
+ hdr[6] = ice->state.default_outer_level[0];
+ break;
+ }
+
+ struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_TESS_CTRL];
+ struct iris_const_buffer *cbuf = &shs->constbuf[0];
+ u_upload_data(ice->ctx.const_uploader, 0, sizeof(hdr), 32,
+ &hdr[0], &cbuf->data.offset,
+ &cbuf->data.res);
+ }
+
for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
if (!(dirty & (IRIS_DIRTY_CONSTANTS_VS << stage)))
continue;
ctx->set_constant_buffer = iris_set_constant_buffer;
ctx->set_shader_buffers = iris_set_shader_buffers;
ctx->set_sampler_views = iris_set_sampler_views;
+ ctx->set_tess_state = iris_set_tess_state;
ctx->set_framebuffer_state = iris_set_framebuffer_state;
ctx->set_polygon_stipple = iris_set_polygon_stipple;
ctx->set_sample_mask = iris_set_sample_mask;