From: Dave Airlie Date: Wed, 17 May 2023 01:20:12 +0000 (+1000) Subject: draw: add mesh pipeline middle end. X-Git-Tag: upstream/23.3.3~7608 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fe0e4bf86376edfb6259a6e0909fa9279bb4b3df;p=platform%2Fupstream%2Fmesa.git draw: add mesh pipeline middle end. This sets up the mesh pipeline to call the post vs clipping and so emit for stats (not for so). Reviewed-by: Roland Scheidegger Part-of: --- diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index b4d314f..8d4be87 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -366,6 +366,11 @@ void draw_vbo(struct draw_context *draw, unsigned num_draws, uint8_t patch_vertices); +void +draw_mesh(struct draw_context *draw, + struct draw_vertex_info *vert_info, + struct draw_prim_info *prim_info); + /******************************************************************************* * Driver backend interface diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 9998884..c62445a 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -177,6 +177,7 @@ struct draw_context struct draw_pt_middle_end *fetch_shade_emit; struct draw_pt_middle_end *general; struct draw_pt_middle_end *llvm; + struct draw_pt_middle_end *mesh; } middle; struct { diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 285832e..2a678dd 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -206,8 +206,10 @@ draw_pt_init(struct draw_context *draw) return FALSE; #ifdef DRAW_LLVM_AVAILABLE - if (draw->llvm) + if (draw->llvm) { draw->pt.middle.llvm = draw_pt_fetch_pipeline_or_emit_llvm(draw); + draw->pt.middle.mesh = draw_pt_mesh_pipeline_or_emit(draw); + } #endif return TRUE; @@ -217,6 +219,11 @@ draw_pt_init(struct draw_context *draw) void draw_pt_destroy(struct draw_context *draw) { + if (draw->pt.middle.mesh) { + draw->pt.middle.mesh->destroy(draw->pt.middle.mesh); + draw->pt.middle.mesh = NULL; + } + if (draw->pt.middle.llvm) { draw->pt.middle.llvm->destroy(draw->pt.middle.llvm); draw->pt.middle.llvm = NULL; @@ -625,3 +632,16 @@ draw_vbo(struct draw_context *draw, } util_fpstate_set(fpstate); } + +/* to be called after a mesh shader is run */ +void +draw_mesh(struct draw_context *draw, + struct draw_vertex_info *vert_info, + struct draw_prim_info *prim_info) +{ + struct draw_pt_middle_end *middle = draw->pt.middle.mesh; + + middle->prepare(middle, 0, 0, NULL); + + draw_mesh_middle_end_run(middle, vert_info, prim_info); +} diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index a6c2152..f03c511 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -151,7 +151,7 @@ struct draw_pt_front_end *draw_pt_vsplit(struct draw_context *draw); struct draw_pt_middle_end *draw_pt_middle_fse(struct draw_context *draw); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw); - +struct draw_pt_middle_end *draw_pt_mesh_pipeline_or_emit(struct draw_context *draw); /******************************************************************************* @@ -268,5 +268,8 @@ draw_pt_split_prim(enum mesa_prim prim, unsigned *first, unsigned *incr); unsigned draw_pt_trim_count(unsigned count, unsigned first, unsigned incr); - +void +draw_mesh_middle_end_run(struct draw_pt_middle_end *middle, + struct draw_vertex_info *vert_info, + struct draw_prim_info *prim_info); #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_mesh_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_mesh_pipeline.c new file mode 100644 index 0000000..3787595 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_mesh_pipeline.c @@ -0,0 +1,131 @@ +/************************************************************************** + * + * Copyright 2023 Red Hat. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_pt.h" +#include "draw/draw_mesh.h" + +/* + * Mesh shader middle end, + * This doesn't need a frontend as mesh shader frontend + * is done with compute shaders in llvmpipe. + */ + +struct mesh_pipeline_middle_end { + struct draw_pt_middle_end base; + struct draw_context *draw; + + struct pt_so_emit *so_emit; + struct pt_post_vs *post_vs; +}; + +/** cast wrapper */ +static inline struct mesh_pipeline_middle_end * +mesh_pipeline_middle_end(struct draw_pt_middle_end *middle) +{ + return (struct mesh_pipeline_middle_end *) middle; +} + +static void +mesh_pipeline_destroy(struct draw_pt_middle_end *middle) +{ + struct mesh_pipeline_middle_end *mpme = mesh_pipeline_middle_end(middle); + + if (mpme->so_emit) + draw_pt_so_emit_destroy(mpme->so_emit); + if (mpme->post_vs) + draw_pt_post_vs_destroy(mpme->post_vs); + FREE(middle); +} + +static void +mesh_middle_end_prepare(struct draw_pt_middle_end *middle, + enum mesa_prim prim, + unsigned opt, + unsigned *max_vertices) +{ + struct mesh_pipeline_middle_end *mpme = mesh_pipeline_middle_end(middle); + struct draw_context *draw = mpme->draw; + enum mesa_prim out_prim = draw->ms.mesh_shader->output_primitive; + unsigned point_clip = draw->rasterizer->fill_front == PIPE_POLYGON_MODE_POINT || + out_prim == MESA_PRIM_POINTS; + draw_pt_post_vs_prepare(mpme->post_vs, + draw->clip_xy, + draw->clip_z, + draw->clip_user, + point_clip ? draw->guard_band_points_lines_xy : + draw->guard_band_xy, + draw->bypass_viewport, + draw->rasterizer->clip_halfz, + FALSE); + + draw_pt_so_emit_prepare(mpme->so_emit, false); + + draw_do_flush(draw, DRAW_FLUSH_BACKEND); + +} + +void +draw_mesh_middle_end_run(struct draw_pt_middle_end *middle, + struct draw_vertex_info *vert_info, + struct draw_prim_info *prim_info) +{ + struct mesh_pipeline_middle_end *mpme = mesh_pipeline_middle_end(middle); + + draw_pt_post_vs_run(mpme->post_vs, vert_info, prim_info); + + /* just for primgen query */ + draw_pt_so_emit(mpme->so_emit, 1, vert_info, prim_info); + draw_pipeline_run_linear(mpme->draw, vert_info, prim_info); +} + +struct draw_pt_middle_end * +draw_pt_mesh_pipeline_or_emit(struct draw_context *draw) +{ + struct mesh_pipeline_middle_end *mpme = + CALLOC_STRUCT(mesh_pipeline_middle_end); + if (!mpme) + goto fail; + + mpme->base.prepare = mesh_middle_end_prepare; + mpme->base.destroy = mesh_pipeline_destroy; + mpme->draw = draw; + + mpme->post_vs = draw_pt_post_vs_create(draw); + if (!mpme->post_vs) + goto fail; + + mpme->so_emit = draw_pt_so_emit_create(draw); + if (!mpme->so_emit) + goto fail; + + return &mpme->base; + fail: + if (mpme) + mesh_pipeline_destroy(&mpme->base); + + return NULL; +} diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 76c4f1a..ed433bd 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -67,6 +67,7 @@ files_libgallium = files( 'draw/draw_pt_fetch.c', 'draw/draw_pt_fetch_shade_emit.c', 'draw/draw_pt_fetch_shade_pipeline.c', + 'draw/draw_pt_mesh_pipeline.c', 'draw/draw_pt.h', 'draw/draw_pt_post_vs.c', 'draw/draw_pt_so_emit.c',