From 8a8edb310d84f1400d8b8b7e096a9dfc33e198b2 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 28 Jul 2022 11:12:42 -0400 Subject: [PATCH] zink: handle unscaled depth bias from nine nine uses this to pass unscaled units for depth bias, which means the units must be scaled based on the format of the depth buffer cc: mesa-stable Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_context.c | 25 +++++++++++++++++++++++++ src/gallium/drivers/zink/zink_context.h | 1 + src/gallium/drivers/zink/zink_draw.cpp | 11 ++++++++--- src/gallium/drivers/zink/zink_screen.c | 14 ++++++++++++++ src/gallium/drivers/zink/zink_screen.h | 2 ++ src/gallium/drivers/zink/zink_state.c | 4 +++- 6 files changed, 53 insertions(+), 4 deletions(-) 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;