diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 967c23e04cd..3c199c7d08c 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -64,6 +64,12 @@ llvmpipe_destroy(struct pipe_context *pipe) if (llvmpipe->csctx) { lp_csctx_destroy(llvmpipe->csctx); } + if (llvmpipe->task_ctx) { + lp_csctx_destroy(llvmpipe->task_ctx); + } + if (llvmpipe->mesh_ctx) { + lp_csctx_destroy(llvmpipe->mesh_ctx); + } if (llvmpipe->blitter) { util_blitter_destroy(llvmpipe->blitter); } @@ -240,6 +246,8 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, llvmpipe_init_vs_funcs(llvmpipe); llvmpipe_init_gs_funcs(llvmpipe); llvmpipe_init_tess_funcs(llvmpipe); + llvmpipe_init_task_funcs(llvmpipe); + llvmpipe_init_mesh_funcs(llvmpipe); llvmpipe_init_rasterizer_funcs(llvmpipe); llvmpipe_init_context_resource_funcs(&llvmpipe->pipe); llvmpipe_init_surface_functions(llvmpipe); @@ -283,6 +291,14 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, if (!llvmpipe->csctx) goto fail; + llvmpipe->task_ctx = lp_csctx_create(&llvmpipe->pipe); + if (!llvmpipe->task_ctx) + goto fail; + + llvmpipe->mesh_ctx = lp_csctx_create(&llvmpipe->pipe); + if (!llvmpipe->mesh_ctx) + goto fail; + llvmpipe->pipe.stream_uploader = u_upload_create_default(&llvmpipe->pipe); if (!llvmpipe->pipe.stream_uploader) goto fail; diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 0b77fa3aa53..2c6d654c959 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -74,6 +74,9 @@ struct llvmpipe_context { const struct lp_velems_state *velems; const struct lp_so_state *so; + struct lp_compute_shader *tss; + struct lp_compute_shader *mhs; + /** Other rendering state */ unsigned sample_mask; unsigned min_samples; @@ -171,6 +174,9 @@ struct llvmpipe_context { unsigned nr_cs_instrs; struct lp_cs_context *csctx; + struct lp_cs_context *task_ctx; + struct lp_cs_context *mesh_ctx; + /** Conditional query object and mode */ struct pipe_query *render_cond_query; enum pipe_render_cond_flag render_cond_mode; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index fab180a8cfb..45382da4c81 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -152,6 +152,12 @@ llvmpipe_init_gs_funcs(struct llvmpipe_context *llvmpipe); void llvmpipe_init_tess_funcs(struct llvmpipe_context *llvmpipe); +void +llvmpipe_init_task_funcs(struct llvmpipe_context *llvmpipe); + +void +llvmpipe_init_mesh_funcs(struct llvmpipe_context *llvmpipe); + void llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe); diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.c b/src/gallium/drivers/llvmpipe/lp_state_cs.c index 70452f69304..a549ccdab78 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.c @@ -51,9 +51,12 @@ #include "util/mesa-sha1.h" #include "nir_serialize.h" +#include "draw/draw_context.h" /** Fragment shader number (for debugging) */ static unsigned cs_no = 0; +static unsigned task_no = 0; +static unsigned mesh_no = 0; struct lp_cs_job_info { unsigned grid_size[3]; @@ -1621,3 +1624,134 @@ lp_csctx_create(struct pipe_context *pipe) csctx->pipe = pipe; return csctx; } + +static void * +llvmpipe_create_ts_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct lp_compute_shader *shader = CALLOC_STRUCT(lp_compute_shader); + if (!shader) + return NULL; + + shader->no = task_no++; + shader->base.type = templ->type; + + shader->base.ir.nir = templ->ir.nir; + shader->req_local_mem += ((struct nir_shader *)shader->base.ir.nir)->info.shared_size; + nir_tgsi_scan_shader(shader->base.ir.nir, &shader->info.base, false); + list_inithead(&shader->variants.list); + + int nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1; + int nr_sampler_views = shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; + int nr_images = shader->info.base.file_max[TGSI_FILE_IMAGE] + 1; + shader->variant_key_size = lp_cs_variant_key_size(MAX2(nr_samplers, nr_sampler_views), nr_images); + return shader; +} + + +static void +llvmpipe_bind_ts_state(struct pipe_context *pipe, void *_task) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (llvmpipe->tss == _task) + return; + + llvmpipe->tss = (struct lp_compute_shader *)_task; +} + +static void +llvmpipe_delete_ts_state(struct pipe_context *pipe, void *_task) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_compute_shader *shader = _task; + struct lp_cs_variant_list_item *li, *next; + + /* Delete all the variants */ + LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) { + llvmpipe_remove_cs_shader_variant(llvmpipe, li->base); + } + if (shader->base.ir.nir) + ralloc_free(shader->base.ir.nir); + FREE(shader); +} + +void +llvmpipe_init_task_funcs(struct llvmpipe_context *llvmpipe) +{ + llvmpipe->pipe.create_ts_state = llvmpipe_create_ts_state; + llvmpipe->pipe.bind_ts_state = llvmpipe_bind_ts_state; + llvmpipe->pipe.delete_ts_state = llvmpipe_delete_ts_state; +} + +static void * +llvmpipe_create_ms_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_compute_shader *shader = CALLOC_STRUCT(lp_compute_shader); + if (!shader) + return NULL; + + shader->no = mesh_no++; + shader->base.type = templ->type; + + shader->base.ir.nir = templ->ir.nir; + shader->req_local_mem += ((struct nir_shader *)shader->base.ir.nir)->info.shared_size; + nir_tgsi_scan_shader(shader->base.ir.nir, &shader->info.base, false); + list_inithead(&shader->variants.list); + + shader->draw_mesh_data = draw_create_mesh_shader(llvmpipe->draw, templ); + if (shader->draw_mesh_data == NULL) { + FREE(shader); + return NULL; + } + + int nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1; + int nr_sampler_views = shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; + int nr_images = shader->info.base.file_max[TGSI_FILE_IMAGE] + 1; + shader->variant_key_size = lp_cs_variant_key_size(MAX2(nr_samplers, nr_sampler_views), nr_images); + return shader; +} + + +static void +llvmpipe_bind_ms_state(struct pipe_context *pipe, void *_mesh) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (llvmpipe->mhs == _mesh) + return; + + llvmpipe->mhs = (struct lp_compute_shader *)_mesh; + + draw_bind_mesh_shader(llvmpipe->draw, _mesh ? llvmpipe->mhs->draw_mesh_data : NULL); +} + + +static void +llvmpipe_delete_ms_state(struct pipe_context *pipe, void *_mesh) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_compute_shader *shader = _mesh; + struct lp_cs_variant_list_item *li, *next; + + /* Delete all the variants */ + LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) { + llvmpipe_remove_cs_shader_variant(llvmpipe, li->base); + } + + draw_delete_mesh_shader(llvmpipe->draw, shader->draw_mesh_data); + if (shader->base.ir.nir) + ralloc_free(shader->base.ir.nir); + + FREE(shader); +} + +void +llvmpipe_init_mesh_funcs(struct llvmpipe_context *llvmpipe) +{ + llvmpipe->pipe.create_ms_state = llvmpipe_create_ms_state; + llvmpipe->pipe.bind_ms_state = llvmpipe_bind_ms_state; + llvmpipe->pipe.delete_ms_state = llvmpipe_delete_ms_state; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.h b/src/gallium/drivers/llvmpipe/lp_state_cs.h index 48d40da40ad..45c0aa86d9e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.h @@ -110,6 +110,7 @@ struct lp_compute_shader { struct lp_tgsi_info info; + struct draw_mesh_shader *draw_mesh_data; uint32_t req_local_mem; /* For debugging/profiling purposes */