zink: lower smooth-lines if not supported

This implements line-smoothing the same way as the draw-module does,
except using a geometry shader instead of a CPU pass.

Ideally, this should be enabled either by checking for the various
smooth-line caps, or by a DRIconf setting.

Unfortunately, RADV doesn't support he smooth-lines features, and we
don't want to force it down a pessimistic shader-key code-path. So that
plan is out the window for now.

While DRIconf is also neat, it's a bit of work to wire up, and we don't
really know of any real-world applications who would need this yet. So,
for now, let's just unconditionally enable is on the IMG proprietary
driver, which is going to need this for sure.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19847>
This commit is contained in:
Erik Faye-Lund 2022-12-06 08:54:34 +01:00 committed by Marge Bot
parent 50d89663c5
commit 80285db9ef
8 changed files with 58 additions and 6 deletions

View File

@ -2801,6 +2801,13 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad
NIR_PASS_V(nir, nir_lower_var_copies);
need_optimize = true;
}
if (zink_gs_key(key)->lower_line_smooth) {
NIR_PASS_V(nir, lower_line_smooth_gs);
NIR_PASS_V(nir, nir_lower_var_copies);
need_optimize = true;
}
if (zink_gs_key(key)->lower_gl_point) {
NIR_PASS_V(nir, lower_gl_point_gs);
need_optimize = true;
@ -2831,6 +2838,12 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad
case MESA_SHADER_FRAGMENT:
if (zink_fs_key(key)->lower_line_stipple)
NIR_PASS_V(nir, lower_line_stipple_fs);
if (zink_fs_key(key)->lower_line_smooth) {
NIR_PASS_V(nir, lower_line_smooth_fs);
need_optimize = true;
}
if (!zink_fs_key(key)->samples &&
nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) {
/* VK will always use gl_SampleMask[] values even if sample count is 0,

View File

@ -803,8 +803,14 @@ zink_draw(struct pipe_context *pctx,
&ctx->tess_levels[0]);
}
if (zink_get_fs_key(ctx)->lower_line_stipple ||
zink_get_gs_key(ctx)->lower_gl_point) {
assert(zink_get_fs_key(ctx)->lower_line_stipple == zink_get_gs_key(ctx)->lower_line_stipple);
zink_get_gs_key(ctx)->lower_gl_point ||
zink_get_fs_key(ctx)->lower_line_smooth) {
assert(zink_get_gs_key(ctx)->lower_line_stipple ==
zink_get_fs_key(ctx)->lower_line_stipple);
assert(zink_get_gs_key(ctx)->lower_line_smooth ==
zink_get_fs_key(ctx)->lower_line_smooth);
float viewport_scale[2] = {
ctx->vp_state.viewport_states[0].scale[0],
@ -823,6 +829,15 @@ zink_draw(struct pipe_context *pctx,
VK_SHADER_STAGE_ALL_GRAPHICS,
offsetof(struct zink_gfx_push_constant, line_stipple_pattern),
sizeof(uint32_t), &stipple);
if (ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.lower_line_smooth) {
float line_width = ctx->rast_state->base.line_width;
VKCTX(CmdPushConstants)(batch->state->cmdbuf,
ctx->curr_program->base.layout,
VK_SHADER_STAGE_ALL_GRAPHICS,
offsetof(struct zink_gfx_push_constant, line_width),
sizeof(uint32_t), &line_width);
}
}
if (have_streamout) {

View File

@ -268,7 +268,8 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
assert(state->rast_prim != PIPE_PRIM_MAX);
VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
if (screen->info.have_EXT_line_rasterization) {
if (screen->info.have_EXT_line_rasterization &&
!state->shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.lower_line_smooth) {
rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
rast_line_state.pNext = rast_state.pNext;
rast_line_state.stippledLineEnable = VK_FALSE;

View File

@ -1851,7 +1851,19 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx)
zink_set_gs_key(ctx)->lower_line_stipple = lower_line_stipple;
}
if (lower_line_stipple || zink_get_gs_key(ctx)->lower_gl_point) {
bool lower_line_smooth = screen->driver_workarounds.no_linesmooth &&
ctx->rast_state->base.line_smooth &&
!ctx->num_so_targets;
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);
zink_set_fs_key(ctx)->lower_line_smooth = lower_line_smooth;
zink_set_gs_key(ctx)->lower_line_smooth = lower_line_smooth;
}
if (lower_line_stipple || lower_line_smooth ||
zink_get_gs_key(ctx)->lower_gl_point) {
enum pipe_shader_type prev_vertex_stage =
ctx->gfx_stages[MESA_SHADER_TESS_EVAL] ?
MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX;

View File

@ -2349,6 +2349,12 @@ init_driver_workarounds(struct zink_screen *screen)
screen->driver_workarounds.no_linestipple = true;
}
if (screen->info.driver_props.driverID ==
VK_DRIVER_ID_IMAGINATION_PROPRIETARY) {
assert(screen->info.feats.features.geometryShader);
screen->driver_workarounds.no_linesmooth = true;
}
/* This is a workarround for the lack of
* gl_PointSize + glPolygonMode(..., GL_LINE), in the imagination
* proprietary driver.
@ -2731,6 +2737,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->info.have_EXT_non_seamless_cube_map &&
!screen->driconf.inline_uniforms &&
!screen->driver_workarounds.no_linestipple &&
!screen->driver_workarounds.no_linesmooth &&
!screen->driver_workarounds.no_hw_gl_point;
if (!screen->optimal_keys)
screen->info.have_EXT_graphics_pipeline_library = false;

View File

@ -60,6 +60,7 @@ struct zink_gs_key {
struct zink_vs_key_base base;
uint8_t pad;
bool lower_line_stipple : 1;
bool lower_line_smooth : 1;
bool lower_gl_point : 1;
// not hashed
unsigned size;
@ -72,7 +73,8 @@ struct zink_fs_key {
bool force_persample_interp : 1;
bool fbfetch_ms : 1;
bool lower_line_stipple : 1;
uint8_t pad : 2;
bool lower_line_smooth : 1;
uint8_t pad : 1;
uint8_t coord_replace_bits;
};

View File

@ -617,7 +617,8 @@ zink_create_rasterizer_state(struct pipe_context *pctx,
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
if (rs_state->line_rectangular) {
if (rs_state->line_smooth)
if (rs_state->line_smooth &&
!screen->driver_workarounds.no_linesmooth)
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
else
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;

View File

@ -1284,6 +1284,7 @@ struct zink_screen {
bool needs_sanitised_layer;
bool track_renderpasses;
bool no_linestipple;
bool no_linesmooth;
bool no_hw_gl_point;
unsigned z16_unscaled_bias;
unsigned z24_unscaled_bias;