From 0ed7b44f5c3b29efd21d2da8681a91b97b2bc655 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Sat, 1 Jan 2022 14:49:28 -0800 Subject: [PATCH] d3d12: Initial plumbing for tesselation Reviewed-by: Boris Brezillon Reviewed-by: Bill Kristiansen Part-of: --- src/gallium/drivers/d3d12/d3d12_blit.cpp | 2 + src/gallium/drivers/d3d12/d3d12_compiler.cpp | 28 +++++++++-- src/gallium/drivers/d3d12/d3d12_context.cpp | 50 +++++++++++++++++++ src/gallium/drivers/d3d12/d3d12_draw.cpp | 2 + src/gallium/drivers/d3d12/d3d12_nir_passes.c | 2 + .../drivers/d3d12/d3d12_pipeline_state.cpp | 14 ++++++ 6 files changed, 93 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_blit.cpp b/src/gallium/drivers/d3d12/d3d12_blit.cpp index 30be203ea12..49e9b9e974e 100644 --- a/src/gallium/drivers/d3d12/d3d12_blit.cpp +++ b/src/gallium/drivers/d3d12/d3d12_blit.cpp @@ -545,6 +545,8 @@ util_blit_save_state(struct d3d12_context *ctx) util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]); util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]); util_blitter_save_geometry_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_GEOMETRY]); + util_blitter_save_tessctrl_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]); + util_blitter_save_tesseval_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]); util_blitter_save_framebuffer(ctx->blitter, &ctx->fb); util_blitter_save_viewport(ctx->blitter, ctx->viewport_states); diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp index 0e6bd2a1c34..92eb08b731b 100644 --- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp +++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp @@ -993,8 +993,6 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele static d3d12_shader_selector * get_prev_shader(struct d3d12_context *ctx, pipe_shader_type current) { - /* No TESS_CTRL or TESS_EVAL yet */ - switch (current) { case PIPE_SHADER_VERTEX: return NULL; @@ -1003,6 +1001,14 @@ get_prev_shader(struct d3d12_context *ctx, pipe_shader_type current) return ctx->gfx_stages[PIPE_SHADER_GEOMETRY]; FALLTHROUGH; case PIPE_SHADER_GEOMETRY: + if (ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]) + return ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]; + FALLTHROUGH; + case PIPE_SHADER_TESS_EVAL: + if (ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]) + return ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]; + FALLTHROUGH; + case PIPE_SHADER_TESS_CTRL: return ctx->gfx_stages[PIPE_SHADER_VERTEX]; default: unreachable("shader type not supported"); @@ -1012,10 +1018,16 @@ get_prev_shader(struct d3d12_context *ctx, pipe_shader_type current) static d3d12_shader_selector * get_next_shader(struct d3d12_context *ctx, pipe_shader_type current) { - /* No TESS_CTRL or TESS_EVAL yet */ - switch (current) { case PIPE_SHADER_VERTEX: + if (ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]) + return ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]; + FALLTHROUGH; + case PIPE_SHADER_TESS_CTRL: + if (ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]) + return ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]; + FALLTHROUGH; + case PIPE_SHADER_TESS_EVAL: if (ctx->gfx_stages[PIPE_SHADER_GEOMETRY]) return ctx->gfx_stages[PIPE_SHADER_GEOMETRY]; FALLTHROUGH; @@ -1218,7 +1230,13 @@ d3d12_create_compute_shader(struct d3d12_context *ctx, void d3d12_select_shader_variants(struct d3d12_context *ctx, const struct pipe_draw_info *dinfo) { - static unsigned order[] = {PIPE_SHADER_VERTEX, PIPE_SHADER_GEOMETRY, PIPE_SHADER_FRAGMENT}; + static unsigned order[] = { + PIPE_SHADER_VERTEX, + PIPE_SHADER_TESS_CTRL, + PIPE_SHADER_TESS_EVAL, + PIPE_SHADER_GEOMETRY, + PIPE_SHADER_FRAGMENT + }; struct d3d12_selection_context sel_ctx; sel_ctx.ctx = ctx; diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index 43ba31794ef..2b048f49cf6 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -1133,6 +1133,48 @@ d3d12_delete_gs_state(struct pipe_context *pctx, void *gs) (struct d3d12_shader_selector *) gs); } +static void * +d3d12_create_tcs_state(struct pipe_context *pctx, + const struct pipe_shader_state *shader) +{ + return d3d12_create_shader(d3d12_context(pctx), PIPE_SHADER_TESS_CTRL, shader); +} + +static void +d3d12_bind_tcs_state(struct pipe_context *pctx, void *tcss) +{ + bind_stage(d3d12_context(pctx), PIPE_SHADER_TESS_CTRL, + (struct d3d12_shader_selector *)tcss); +} + +static void +d3d12_delete_tcs_state(struct pipe_context *pctx, void *tcs) +{ + delete_shader(d3d12_context(pctx), PIPE_SHADER_TESS_CTRL, + (struct d3d12_shader_selector *)tcs); +} + +static void * +d3d12_create_tes_state(struct pipe_context *pctx, + const struct pipe_shader_state *shader) +{ + return d3d12_create_shader(d3d12_context(pctx), PIPE_SHADER_TESS_EVAL, shader); +} + +static void +d3d12_bind_tes_state(struct pipe_context *pctx, void *tess) +{ + bind_stage(d3d12_context(pctx), PIPE_SHADER_TESS_EVAL, + (struct d3d12_shader_selector *)tess); +} + +static void +d3d12_delete_tes_state(struct pipe_context *pctx, void *tes) +{ + delete_shader(d3d12_context(pctx), PIPE_SHADER_TESS_EVAL, + (struct d3d12_shader_selector *)tes); +} + static void * d3d12_create_compute_state(struct pipe_context *pctx, const struct pipe_compute_state *shader) @@ -2272,6 +2314,14 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->base.bind_gs_state = d3d12_bind_gs_state; ctx->base.delete_gs_state = d3d12_delete_gs_state; + ctx->base.create_tcs_state = d3d12_create_tcs_state; + ctx->base.bind_tcs_state = d3d12_bind_tcs_state; + ctx->base.delete_tcs_state = d3d12_delete_tcs_state; + + ctx->base.create_tes_state = d3d12_create_tes_state; + ctx->base.bind_tes_state = d3d12_bind_tes_state; + ctx->base.delete_tes_state = d3d12_delete_tes_state; + ctx->base.create_compute_state = d3d12_create_compute_state; ctx->base.bind_compute_state = d3d12_bind_compute_state; ctx->base.delete_compute_state = d3d12_delete_compute_state; diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index cef00097c01..40dd5391095 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -708,6 +708,8 @@ d3d12_last_vertex_stage(struct d3d12_context *ctx) { struct d3d12_shader_selector *sel = ctx->gfx_stages[PIPE_SHADER_GEOMETRY]; if (!sel || sel->is_gs_variant) + sel = ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]; + if (!sel) sel = ctx->gfx_stages[PIPE_SHADER_VERTEX]; return sel; } diff --git a/src/gallium/drivers/d3d12/d3d12_nir_passes.c b/src/gallium/drivers/d3d12/d3d12_nir_passes.c index 38e0fc19e53..8016a4e847b 100644 --- a/src/gallium/drivers/d3d12/d3d12_nir_passes.c +++ b/src/gallium/drivers/d3d12/d3d12_nir_passes.c @@ -95,6 +95,7 @@ d3d12_lower_yflip(nir_shader *nir) nir_variable *flip = NULL; if (nir->info.stage != MESA_SHADER_VERTEX && + nir->info.stage != MESA_SHADER_TESS_EVAL && nir->info.stage != MESA_SHADER_GEOMETRY) return; @@ -390,6 +391,7 @@ void d3d12_nir_invert_depth(nir_shader *shader) { if (shader->info.stage != MESA_SHADER_VERTEX && + shader->info.stage != MESA_SHADER_TESS_EVAL && shader->info.stage != MESA_SHADER_GEOMETRY) return; diff --git a/src/gallium/drivers/d3d12/d3d12_pipeline_state.cpp b/src/gallium/drivers/d3d12/d3d12_pipeline_state.cpp index a53bcfe27a8..071986a19b4 100644 --- a/src/gallium/drivers/d3d12/d3d12_pipeline_state.cpp +++ b/src/gallium/drivers/d3d12/d3d12_pipeline_state.cpp @@ -213,6 +213,20 @@ create_gfx_pipeline_state(struct d3d12_context *ctx) last_vertex_stage_nir = shader->nir; } + if (state->stages[PIPE_SHADER_TESS_CTRL]) { + auto shader = state->stages[PIPE_SHADER_TESS_CTRL]; + pso_desc.HS.BytecodeLength = shader->bytecode_length; + pso_desc.HS.pShaderBytecode = shader->bytecode; + last_vertex_stage_nir = shader->nir; + } + + if (state->stages[PIPE_SHADER_TESS_EVAL]) { + auto shader = state->stages[PIPE_SHADER_TESS_EVAL]; + pso_desc.DS.BytecodeLength = shader->bytecode_length; + pso_desc.DS.pShaderBytecode = shader->bytecode; + last_vertex_stage_nir = shader->nir; + } + if (state->stages[PIPE_SHADER_GEOMETRY]) { auto shader = state->stages[PIPE_SHADER_GEOMETRY]; pso_desc.GS.BytecodeLength = shader->bytecode_length;