diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index dc0f70823ca..7ebfbaa2d26 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2896,6 +2896,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx, } if (ctx->gfx_pipeline_state.void_alpha_attachments != prev_void_alpha_attachments) ctx->gfx_pipeline_state.dirty = true; + unsigned depth_bias_scale_factor = ctx->depth_bias_scale_factor; if (ctx->fb_state.zsbuf) { struct pipe_surface *psurf = ctx->fb_state.zsbuf; struct zink_surface *transient = zink_transient_surface(psurf); @@ -2906,7 +2907,31 @@ zink_set_framebuffer_state(struct pipe_context *pctx, if (zink_csurface(psurf)->info.layerCount > layers) ctx->fb_layer_mismatch |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS); zink_resource(psurf->texture)->fb_binds++; + switch (psurf->format) { + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z16_UNORM_S8_UINT: + ctx->depth_bias_scale_factor = zink_screen(ctx->base.screen)->driver_workarounds.z16_unscaled_bias; + break; + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_X24S8_UINT: + case PIPE_FORMAT_X8Z24_UNORM: + ctx->depth_bias_scale_factor = zink_screen(ctx->base.screen)->driver_workarounds.z24_unscaled_bias; + break; + case PIPE_FORMAT_Z32_FLOAT: + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + case PIPE_FORMAT_Z32_UNORM: + ctx->depth_bias_scale_factor = 1<<23; + break; + default: + ctx->depth_bias_scale_factor = 0; + } + } else { + ctx->depth_bias_scale_factor = 0; } + if (depth_bias_scale_factor != ctx->depth_bias_scale_factor && + ctx->rast_state && ctx->rast_state->base.offset_units_unscaled) + ctx->rast_state_changed = true; rebind_fb_state(ctx, NULL, true); ctx->fb_state.samples = MAX2(samples, 1); zink_update_framebuffer_state(ctx); diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 30c3151a8c9..5549474c081 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -271,6 +271,7 @@ struct zink_context { VkRenderingInfo info; } dynamic_fb; uint32_t fb_layer_mismatch; //bitmask + unsigned depth_bias_scale_factor; struct set rendering_state_cache; struct set render_pass_state_cache; struct hash_table *render_pass_cache; diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index dd0d2f8fc4e..8e5083897f6 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -696,10 +696,15 @@ zink_draw(struct pipe_context *pctx, } VKCTX(CmdSetLineWidth)(batch->state->cmdbuf, rast_state->line_width); - if (depth_bias) - VKCTX(CmdSetDepthBias)(batch->state->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale); - else + if (depth_bias) { + if (rast_state->base.offset_units_unscaled) { + VKCTX(CmdSetDepthBias)(batch->state->cmdbuf, rast_state->offset_units * ctx->depth_bias_scale_factor, rast_state->offset_clamp, rast_state->offset_scale); + } else { + VKCTX(CmdSetDepthBias)(batch->state->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale); + } + } else { VKCTX(CmdSetDepthBias)(batch->state->cmdbuf, 0.0f, 0.0f, 0.0f); + } } ctx->rast_state_changed = false; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 0db129a22a0..156781b28d8 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -466,6 +466,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: return screen->info.have_KHR_sampler_mirror_clamp_to_edge; + case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: + return 1; + case PIPE_CAP_POLYGON_OFFSET_CLAMP: return screen->info.feats.features.depthBiasClamp; @@ -2121,6 +2124,17 @@ init_driver_workarounds(struct zink_screen *screen) /* performance */ screen->info.border_color_feats.customBorderColorWithoutFormat = VK_FALSE; } + 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 || + screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV) + screen->driver_workarounds.z24_unscaled_bias = 1<<23; + else + screen->driver_workarounds.z24_unscaled_bias = 1<<24; + if (screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) + screen->driver_workarounds.z16_unscaled_bias = 1<<15; + else + screen->driver_workarounds.z16_unscaled_bias = 1<<16; } static struct zink_screen * diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index 789f054fdf3..75edba81052 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -211,6 +211,8 @@ struct zink_screen { bool depth_clip_control_missing; bool implicit_sync; bool force_pipeline_library; + unsigned z16_unscaled_bias; + unsigned z24_unscaled_bias; } driver_workarounds; }; diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index c4ffa83afc2..ed21b4c194d 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -611,7 +611,9 @@ zink_create_rasterizer_state(struct pipe_context *pctx, state->offset_point = rs_state->offset_point; state->offset_line = rs_state->offset_line; state->offset_tri = rs_state->offset_tri; - state->offset_units = rs_state->offset_units * 2; + state->offset_units = rs_state->offset_units; + if (!rs_state->offset_units_unscaled) + state->offset_units *= 2; state->offset_clamp = rs_state->offset_clamp; state->offset_scale = rs_state->offset_scale;