From 90a8525d703330b9d198ddf9579c560d0e5cadaa Mon Sep 17 00:00:00 2001 From: antonino Date: Fri, 3 Feb 2023 11:44:39 +0100 Subject: [PATCH] zink: handle edgeflags Vulkan has no support for edgeflags. If the user has a geometry shader bound nothing needs to be done as edgeflags don't work with them, otherwise a geometry shader that emulates them is generated. Reviewed-by: Mike Blumenkrantz Reviewed-by: Erik Faye-Lund Part-of: --- .../drivers/zink/ci/zink-anv-tgl-fails.txt | 6 -- .../drivers/zink/ci/zink-lvp-fails.txt | 4 -- .../zink/ci/zink-radv-navi10-fails.txt | 4 -- .../zink/ci/zink-radv-vangogh-fails.txt | 4 -- src/gallium/drivers/zink/zink_draw.cpp | 9 ++- src/gallium/drivers/zink/zink_program.c | 70 ++++++++++++++++++- src/gallium/drivers/zink/zink_program.h | 3 + 7 files changed, 76 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt index c1fedfeec9b..ac4c7d820ed 100644 --- a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt @@ -132,9 +132,6 @@ shaders@point-vertex-id gl_vertexid gl_instanceid divisor,Fail shaders@point-vertex-id gl_vertexid gl_instanceid,Fail shaders@point-vertex-id gl_vertexid,Fail -spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail -spec@!opengl 1.0@gl-1.0-edgeflag,Fail - spec@!opengl 1.0@gl-1.0-no-op-paths,Fail spec@!opengl 1.0@gl-1.0-spot-light,Fail @@ -178,9 +175,6 @@ spec@!opengl 1.1@linestipple,Fail # (and more) spec@!opengl 1.1@polygon-mode,Fail -spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail -spec@!opengl 2.0@gl-2.0-edgeflag,Fail - spec@!opengl 2.0@vs-point_size-zero,Fail spec@!opengl 2.1@pbo,Fail diff --git a/src/gallium/drivers/zink/ci/zink-lvp-fails.txt b/src/gallium/drivers/zink/ci/zink-lvp-fails.txt index d7cef83a52c..d7f5154a835 100644 --- a/src/gallium/drivers/zink/ci/zink-lvp-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-lvp-fails.txt @@ -52,8 +52,6 @@ shaders@point-vertex-id gl_vertexid,Fail shaders@point-vertex-id gl_vertexid divisor,Fail shaders@point-vertex-id gl_vertexid gl_instanceid,Fail shaders@point-vertex-id gl_vertexid gl_instanceid divisor,Fail -spec@!opengl 1.0@gl-1.0-edgeflag,Fail -spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail spec@!opengl 1.0@gl-1.0-no-op-paths,Fail spec@!opengl 1.1@linestipple,Fail spec@!opengl 1.1@linestipple@Factor 2x,Fail @@ -77,8 +75,6 @@ spec@!opengl 1.1@polygon-mode-offset@config 6: Expected blue pixel in center,Fai spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on right edge,Fail spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge,Fail spec@!opengl 1.2@copyteximage 3d,Fail -spec@!opengl 2.0@gl-2.0-edgeflag,Fail -spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail spec@!opengl 2.1@pbo,Fail spec@!opengl 2.1@pbo@test_polygon_stip,Fail spec@!opengl 2.1@polygon-stipple-fs,Fail diff --git a/src/gallium/drivers/zink/ci/zink-radv-navi10-fails.txt b/src/gallium/drivers/zink/ci/zink-radv-navi10-fails.txt index 0c0d650082c..38766709651 100644 --- a/src/gallium/drivers/zink/ci/zink-radv-navi10-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-radv-navi10-fails.txt @@ -301,8 +301,6 @@ spec@khr_texture_compression_astc@sliced-3d-miptree-gl srgb-fp,Fail spec@khr_texture_compression_astc@sliced-3d-miptree-gl srgb-fp@sRGB decode full precision,Fail spec@oes_shader_io_blocks@compiler@layout-location-aliasing.vert,Fail -spec@!opengl 1.0@gl-1.0-edgeflag,Fail -spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail spec@!opengl 1.0@gl-1.0-no-op-paths,Fail spec@!opengl 1.1@linestipple@Factor 2x,Fail spec@!opengl 1.1@linestipple@Factor 3x,Fail @@ -326,8 +324,6 @@ spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge, spec@!opengl 1.1@polygon-mode-offset,Fail spec@!opengl 1.5@depth-tex-compare,Fail -spec@!opengl 2.0@gl-2.0-edgeflag,Fail -spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail spec@!opengl 2.0@vs-point_size-zero,Fail spec@!opengl 2.1@pbo,Fail spec@!opengl 2.1@pbo@test_polygon_stip,Fail diff --git a/src/gallium/drivers/zink/ci/zink-radv-vangogh-fails.txt b/src/gallium/drivers/zink/ci/zink-radv-vangogh-fails.txt index 538a1c8c0b4..31358e088a0 100644 --- a/src/gallium/drivers/zink/ci/zink-radv-vangogh-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-radv-vangogh-fails.txt @@ -300,8 +300,6 @@ spec@khr_texture_compression_astc@sliced-3d-miptree-gl srgb-fp,Fail spec@khr_texture_compression_astc@sliced-3d-miptree-gl srgb-fp@sRGB decode full precision,Fail spec@oes_shader_io_blocks@compiler@layout-location-aliasing.vert,Fail -spec@!opengl 1.0@gl-1.0-edgeflag,Fail -spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail spec@!opengl 1.0@gl-1.0-no-op-paths,Fail spec@!opengl 1.1@linestipple@Factor 2x,Fail spec@!opengl 1.1@linestipple@Factor 3x,Fail @@ -325,8 +323,6 @@ spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge, spec@!opengl 1.1@polygon-mode-offset,Fail spec@!opengl 1.5@depth-tex-compare,Fail -spec@!opengl 2.0@gl-2.0-edgeflag,Fail -spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail spec@!opengl 2.0@vs-point_size-zero,Fail spec@!opengl 2.1@pbo,Fail spec@!opengl 2.1@pbo@test_polygon_stip,Fail diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 19c89c890ed..f370bc773fb 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -506,9 +506,12 @@ zink_draw(struct pipe_context *pctx, } ctx->gfx_pipeline_state.gfx_prim_mode = mode; - if (!screen->optimal_keys && - (lines_changed || points_changed || rast_state_changed || ctx->gfx_pipeline_state.modules_changed)) - zink_set_primitive_emulation_keys(ctx); + if ((mode_changed || points_changed || lines_changed || rast_state_changed || ctx->gfx_pipeline_state.modules_changed)) { + if (screen->optimal_keys) + zink_create_primitive_emulation_gs(ctx); + else + zink_set_primitive_emulation_keys(ctx); + } if (index_size) { const VkIndexType index_type[3] = { diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index e535ad00ac1..34f64a99db5 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -2172,6 +2172,34 @@ zink_driver_thread_add_job(struct pipe_screen *pscreen, void *data, util_queue_add_job(&screen->cache_get_thread, data, fence, execute, cleanup, job_size); } +static bool +has_edge_flags(struct zink_context *ctx) +{ + switch(ctx->gfx_pipeline_state.gfx_prim_mode) { + case PIPE_PRIM_POINTS: + case PIPE_PRIM_LINE_STRIP: + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + case PIPE_PRIM_LINES: + case PIPE_PRIM_LINE_LOOP: + case PIPE_PRIM_LINES_ADJACENCY: + case PIPE_PRIM_TRIANGLE_STRIP: + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + case PIPE_PRIM_QUAD_STRIP: + return false; + case PIPE_PRIM_TRIANGLES: + case PIPE_PRIM_TRIANGLES_ADJACENCY: + case PIPE_PRIM_QUADS: + case PIPE_PRIM_POLYGON: + case PIPE_PRIM_PATCHES: + case PIPE_PRIM_MAX: + default: + break; + } + return ctx->gfx_pipeline_state.rast_prim == PIPE_PRIM_LINES && + ctx->gfx_stages[MESA_SHADER_VERTEX]->has_edgeflags; +} + void zink_set_primitive_emulation_keys(struct zink_context *ctx) { @@ -2197,6 +2225,8 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) ctx->rast_state->base.line_smooth && !ctx->num_so_targets; + bool lower_edge_flags = has_edge_flags(ctx); + if (zink_get_fs_key(ctx)->lower_line_smooth != lower_line_smooth) { assert(zink_get_gs_key(ctx)->lower_line_smooth == zink_get_fs_key(ctx)->lower_line_smooth); @@ -2208,7 +2238,7 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) zink_set_fs_key(ctx)->lower_point_smooth = lower_point_smooth; } - if (lower_line_stipple || lower_line_smooth || + if (lower_line_stipple || lower_line_smooth || lower_edge_flags || zink_get_gs_key(ctx)->lower_gl_point) { enum pipe_shader_type prev_vertex_stage = ctx->gfx_stages[MESA_SHADER_TESS_EVAL] ? @@ -2222,8 +2252,42 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) nir_shader *nir = nir_create_passthrough_gs( &screen->nir_options, ctx->gfx_stages[prev_vertex_stage]->nir, - (lower_line_stipple || lower_line_smooth) ? SHADER_PRIM_LINE_STRIP : SHADER_PRIM_POINTS, - false); + ctx->gfx_pipeline_state.gfx_prim_mode, + lower_edge_flags); + + struct zink_shader *shader = zink_shader_create(screen, nir, NULL); + ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs[ctx->gfx_pipeline_state.gfx_prim_mode] = shader; + shader->non_fs.is_generated = true; + } + + bind_gfx_stage(ctx, MESA_SHADER_GEOMETRY, + ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs[ctx->gfx_pipeline_state.gfx_prim_mode]); + } + } else if (ctx->gfx_stages[MESA_SHADER_GEOMETRY] && + ctx->gfx_stages[MESA_SHADER_GEOMETRY]->non_fs.is_generated) + bind_gfx_stage(ctx, MESA_SHADER_GEOMETRY, NULL); +} + +void +zink_create_primitive_emulation_gs(struct zink_context *ctx) +{ + struct zink_screen *screen = zink_screen(ctx->base.screen); + bool lower_edge_flags = has_edge_flags(ctx); + + if (lower_edge_flags) { + enum pipe_shader_type prev_vertex_stage = + ctx->gfx_stages[MESA_SHADER_TESS_EVAL] ? + MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX; + + if (!ctx->gfx_stages[MESA_SHADER_GEOMETRY] || + (ctx->gfx_stages[MESA_SHADER_GEOMETRY]->nir->info.gs.input_primitive != ctx->gfx_pipeline_state.gfx_prim_mode)) { + + if (!ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs[ctx->gfx_pipeline_state.gfx_prim_mode]) { + nir_shader *nir = nir_create_passthrough_gs( + &screen->nir_options, + ctx->gfx_stages[prev_vertex_stage]->nir, + ctx->gfx_pipeline_state.gfx_prim_mode, + lower_edge_flags); struct zink_shader *shader = zink_shader_create(screen, nir, NULL); ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs[ctx->gfx_pipeline_state.gfx_prim_mode] = shader; diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 1a8d287083c..5633ea5a3e4 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -363,6 +363,9 @@ zink_set_fs_point_coord_key(struct zink_context *ctx) void zink_set_primitive_emulation_keys(struct zink_context *ctx); +void +zink_create_primitive_emulation_gs(struct zink_context *ctx); + static inline const struct zink_shader_key_base * zink_get_shader_key_base(const struct zink_context *ctx, gl_shader_stage pstage) {