st/nine: Use offset_units_unscaled
authorAxel Davy <axel.davy@ens.fr>
Tue, 14 Jun 2016 21:24:24 +0000 (23:24 +0200)
committerAxel Davy <axel.davy@ens.fr>
Sat, 25 Jun 2016 08:16:15 +0000 (10:16 +0200)
offset_units_unscaled enables proper support
for depth bias for gallium nine. Use it
if available.

Solves issues with some games using depth bias.
For example:
https://github.com/iXit/Mesa-3D/issues/220

Signed-off-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/device9.c
src/gallium/state_trackers/nine/device9.h
src/gallium/state_trackers/nine/nine_pipe.c
src/gallium/state_trackers/nine/nine_pipe.h
src/gallium/state_trackers/nine/nine_state.c

index bb1735aae7bb15b2e041afe970a97af0330096ae..b4ce3c85e218da9f99400d4d9706e859dd240485 100644 (file)
@@ -427,6 +427,7 @@ NineDevice9_ctor( struct NineDevice9 *This,
     This->driver_caps.window_space_position_support = GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION);
     This->driver_caps.vs_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS);
     This->driver_caps.ps_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_INTEGERS);
+    This->driver_caps.offset_units_unscaled = GET_PCAP(POLYGON_OFFSET_UNITS_UNSCALED);
 
     nine_ff_init(This); /* initialize fixed function code */
 
index 73a43cf08ffe24535a12972b6197071836dcce28..d584a3558ab89abcafc4e8d83e393d0af06cc398 100644 (file)
@@ -121,6 +121,7 @@ struct NineDevice9
         boolean window_space_position_support;
         boolean vs_integer;
         boolean ps_integer;
+        boolean offset_units_unscaled;
     } driver_caps;
 
     struct {
index 79b910c482fba7bd309e39315930496b2da7ff31..c1814fe88e06e77a4fcf432453a5486e23e1cad9 100644 (file)
@@ -70,7 +70,9 @@ nine_convert_dsa_state(struct pipe_depth_stencil_alpha_state *dsa_state,
 }
 
 void
-nine_convert_rasterizer_state(struct pipe_rasterizer_state *rast_state, const DWORD *rs)
+nine_convert_rasterizer_state(struct NineDevice9 *device,
+                              struct pipe_rasterizer_state *rast_state,
+                              const DWORD *rs)
 {
     struct pipe_rasterizer_state rast;
 
@@ -120,14 +122,12 @@ nine_convert_rasterizer_state(struct pipe_rasterizer_state *rast_state, const DW
     /* offset_units has the ogl/d3d11 meaning.
      * d3d9: offset = scale * dz + bias
      * ogl/d3d11: offset = scale * dz + r * bias
-     * with r implementation dependant and is supposed to be
-     * the smallest value the depth buffer format can hold.
-     * In practice on current and past hw it seems to be 2^-23
-     * for all formats except float formats where it varies depending
-     * on the content.
-     * For now use 1 << 23, but in the future perhaps add a way in gallium
-     * to get r for the format or get the gallium behaviour */
-    rast.offset_units = asfloat(rs[D3DRS_DEPTHBIAS]) * (float)(1 << 23);
+     * with r implementation dependent (+ different formula for float depth
+     * buffers). r=2^-23 is often the right value for gallium drivers.
+     * If possible, use offset_units_unscaled, which gives the d3d9
+     * behaviour, else scale by 1 << 23 */
+    rast.offset_units = asfloat(rs[D3DRS_DEPTHBIAS]) * (device->driver_caps.offset_units_unscaled ? 1.0f : (float)(1 << 23));
+    rast.offset_units_unscaled = device->driver_caps.offset_units_unscaled;
     rast.offset_scale = asfloat(rs[D3DRS_SLOPESCALEDEPTHBIAS]);
  /* rast.offset_clamp = 0.0f; */
 
index 4d2bc922539f0c8c894edc687c2706371b9a0ab5..fe8e91013d8517510f46347abd7f1f9cd225fab4 100644 (file)
@@ -38,7 +38,7 @@ extern const enum pipe_format nine_d3d9_to_pipe_format_map[120];
 extern const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT];
 
 void nine_convert_dsa_state(struct pipe_depth_stencil_alpha_state *, const DWORD *);
-void nine_convert_rasterizer_state(struct pipe_rasterizer_state *, const DWORD *);
+void nine_convert_rasterizer_state(struct NineDevice9 *, struct pipe_rasterizer_state *, const DWORD *);
 void nine_convert_blend_state(struct pipe_blend_state *, const DWORD *);
 void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *);
 
index 095c998876d950f3695494c2491efa1cf2d76110..6aa632501122cdd8b8b3d758f62309bfa1003a6f 100644 (file)
@@ -74,7 +74,7 @@ prepare_dsa(struct NineDevice9 *device)
 static inline void
 prepare_rasterizer(struct NineDevice9 *device)
 {
-    nine_convert_rasterizer_state(&device->state.pipe.rast, device->state.rs);
+    nine_convert_rasterizer_state(device, &device->state.pipe.rast, device->state.rs);
     device->state.commit |= NINE_STATE_COMMIT_RASTERIZER;
 }