diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 852c1277dc0..87e936306b8 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -2551,6 +2551,10 @@ 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_gl_point) { + NIR_PASS_V(nir, lower_gl_point_gs); + need_optimize = true; + } break; default: diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 17b0944e3c2..fbcb04f2c19 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -800,8 +800,9 @@ zink_draw(struct pipe_context *pctx, offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6, &ctx->tess_levels[0]); } - if (zink_get_fs_key(ctx)->lower_line_stipple) { - assert(zink_get_gs_key(ctx)->lower_line_stipple); + 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); float viewport_scale[2] = { ctx->vp_state.viewport_states[0].scale[0], diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index a6737958732..e61e86167db 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -1851,7 +1851,7 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) zink_set_gs_key(ctx)->lower_line_stipple = lower_line_stipple; } - if (lower_line_stipple) { + if (lower_line_stipple || 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; @@ -1863,7 +1863,9 @@ 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, - SHADER_PRIM_LINE_STRIP, 2); + lower_line_stipple ? SHADER_PRIM_LINE_STRIP : SHADER_PRIM_POINTS, + lower_line_stipple ? 2 : 1); + NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream); struct zink_shader *shader = zink_shader_create(screen, nir, NULL); ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs = shader; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 842a8682c0f..8093891ae0c 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -2349,6 +2349,19 @@ init_driver_workarounds(struct zink_screen *screen) screen->driver_workarounds.no_linestipple = true; } + /* This is a workarround for the lack of + * gl_PointSize + glPolygonMode(..., GL_LINE), in the imagination + * proprietary driver. + */ + switch (screen->info.driver_props.driverID) { + case VK_DRIVER_ID_IMAGINATION_PROPRIETARY: + screen->driver_workarounds.no_hw_gl_point = true; + break; + default: + screen->driver_workarounds.no_hw_gl_point = false; + break; + } + if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE || screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY || screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY || @@ -2717,7 +2730,8 @@ zink_internal_create_screen(const struct pipe_screen_config *config) screen->optimal_keys = !screen->need_decompose_attrs && screen->info.have_EXT_non_seamless_cube_map && !screen->driconf.inline_uniforms && - !screen->driver_workarounds.no_linestipple; + !screen->driver_workarounds.no_linestipple && + !screen->driver_workarounds.no_hw_gl_point; if (!screen->optimal_keys) screen->info.have_EXT_graphics_pipeline_library = false; diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h index 43b4ec648f8..93cfec503fc 100644 --- a/src/gallium/drivers/zink/zink_shader_keys.h +++ b/src/gallium/drivers/zink/zink_shader_keys.h @@ -60,6 +60,7 @@ struct zink_gs_key { struct zink_vs_key_base base; uint8_t pad; bool lower_line_stipple : 1; + bool lower_gl_point : 1; // not hashed unsigned size; }; diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index c94f73b44db..f1d0351bb1c 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -601,8 +601,15 @@ zink_create_rasterizer_state(struct pipe_context *pctx, assert(rs_state->fill_front <= PIPE_POLYGON_MODE_POINT); if (rs_state->fill_back != rs_state->fill_front) debug_printf("BUG: vulkan doesn't support different front and back fill modes\n"); - state->hw_state.polygon_mode = rs_state->fill_front; // same values - state->cull_mode = rs_state->cull_face; // same bits + + if (rs_state->fill_front == PIPE_POLYGON_MODE_POINT && + screen->driver_workarounds.no_hw_gl_point) { + state->hw_state.polygon_mode = VK_POLYGON_MODE_FILL; + state->cull_mode = VK_CULL_MODE_NONE; + } else { + state->hw_state.polygon_mode = rs_state->fill_front; // same values + state->cull_mode = rs_state->cull_face; // same bits + } state->front_face = rs_state->front_ccw ? VK_FRONT_FACE_COUNTER_CLOCKWISE : @@ -670,6 +677,11 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso) ctx->vp_state_changed = true; } + bool lower_gl_point = screen->driver_workarounds.no_hw_gl_point; + lower_gl_point &= ctx->rast_state->base.fill_front == PIPE_POLYGON_MODE_POINT; + if (zink_get_gs_key(ctx)->lower_gl_point != lower_gl_point) + zink_set_gs_key(ctx)->lower_gl_point = lower_gl_point; + if (ctx->gfx_pipeline_state.dyn_state1.front_face != ctx->rast_state->front_face) { ctx->gfx_pipeline_state.dyn_state1.front_face = ctx->rast_state->front_face; ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 490d1122f02..0a402de6b50 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1282,6 +1282,7 @@ struct zink_screen { bool needs_sanitised_layer; bool track_renderpasses; bool no_linestipple; + bool no_hw_gl_point; unsigned z16_unscaled_bias; unsigned z24_unscaled_bias; } driver_workarounds;