<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">
Reviewed-by: Tim Rowley <<a href="mailto:timothy.o.rowley@intel.com" class="">timothy.o.rowley@intel.com</a>>
<div class=""><br class="">
<div style="">
<blockquote type="cite" class="">
<div class="">On Mar 1, 2017, at 10:58 PM, Bruce Cherniak <<a href="mailto:bruce.cherniak@intel.com" class="">bruce.cherniak@intel.com</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div class="">Recent change to st/mesa state update logic caused major regressions to<br class="">
swr validation code.<br class="">
<br class="">
swr uses the same validation logic (swr_update_derived) for both draw<br class="">
and Clear calls.  New st/mesa state update logic results in certain state<br class="">
objects not being set/bound during Clear.  This was causing null ptr<br class="">
exceptions.  Creation of static dummy state objects allows setting these<br class="">
pointers during Clear validation, without interfering with relevant state<br class="">
validation.<br class="">
<br class="">
Once fixed, new logic also highlighted an error in dirty bit checking for<br class="">
fragment shader and clip validation.<br class="">
<br class="">
(The alternative is to have a simplified validation routine for Clear.<br class="">
Which may do that at some point.)<br class="">
---<br class="">
src/gallium/drivers/swr/swr_shader.cpp |  6 +++++<br class="">
src/gallium/drivers/swr/swr_state.cpp  | 43 +++++++++++++++++++++++++++++++---<br class="">
2 files changed, 46 insertions(+), 3 deletions(-)<br class="">
<br class="">
diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp<br class="">
index 676938c..9169f6d 100644<br class="">
--- a/src/gallium/drivers/swr/swr_shader.cpp<br class="">
+++ b/src/gallium/drivers/swr/swr_shader.cpp<br class="">
@@ -366,6 +366,9 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key)<br class="">
PFN_VERTEX_FUNC<br class="">
swr_compile_vs(struct swr_context *ctx, swr_jit_vs_key &key)<br class="">
{<br class="">
+   if (!ctx->vs->pipe.tokens)<br class="">
+      return NULL;<br class="">
+<br class="">
   BuilderSWR builder(<br class="">
      reinterpret_cast<JitManager *>(swr_screen(ctx->pipe.screen)->hJitMgr),<br class="">
      "VS");<br class="">
@@ -726,6 +729,9 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)<br class="">
PFN_PIXEL_KERNEL<br class="">
swr_compile_fs(struct swr_context *ctx, swr_jit_fs_key &key)<br class="">
{<br class="">
+   if (!ctx->fs->pipe.tokens)<br class="">
+      return NULL;<br class="">
+<br class="">
   BuilderSWR builder(<br class="">
      reinterpret_cast<JitManager *>(swr_screen(ctx->pipe.screen)->hJitMgr),<br class="">
      "FS");<br class="">
diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp<br class="">
index 5e3d58d..e1f1734 100644<br class="">
--- a/src/gallium/drivers/swr/swr_state.cpp<br class="">
+++ b/src/gallium/drivers/swr/swr_state.cpp<br class="">
@@ -914,6 +914,39 @@ swr_update_derived(struct pipe_context *pipe,<br class="">
   struct swr_context *ctx = swr_context(pipe);<br class="">
   struct swr_screen *screen = swr_screen(pipe->screen);<br class="">
<br class="">
+   /* When called from swr_clear (p_draw_info = null), set any null<br class="">
+    * state-objects to the dummy state objects to prevent nullptr dereference<br class="">
+    * in validation below.<br class="">
+    *<br class="">
+    * Important that this remains static for zero initialization.  These<br class="">
+    * aren't meant to be proper state objects, just empty structs. They will<br class="">
+    * not be written to.<br class="">
+    *<br class="">
+    * Shaders can't be part of the union since they contain std::unordered_map<br class="">
+    */<br class="">
+   static struct {<br class="">
+      union {<br class="">
+         struct pipe_rasterizer_state rasterizer;<br class="">
+         struct pipe_depth_stencil_alpha_state depth_stencil;<br class="">
+         struct swr_blend_state blend;<br class="">
+      } state;<br class="">
+      struct swr_vertex_shader vs;<br class="">
+      struct swr_fragment_shader fs;<br class="">
+   } swr_dummy;<br class="">
+<br class="">
+   if (!p_draw_info) {<br class="">
+      if (!ctx->rasterizer)<br class="">
+         ctx->rasterizer = &swr_dummy.state.rasterizer;<br class="">
+      if (!ctx->depth_stencil)<br class="">
+         ctx->depth_stencil = &swr_dummy.state.depth_stencil;<br class="">
+      if (!ctx->blend)<br class="">
+         ctx->blend = &swr_dummy.state.blend;<br class="">
+      if (!ctx->vs)<br class="">
+         ctx->vs = &swr_dummy.vs;<br class="">
+      if (!ctx->fs)<br class="">
+         ctx->fs = &swr_dummy.fs;<br class="">
+   }<br class="">
+<br class="">
   /* Update screen->pipe to current pipe context. */<br class="">
   if (screen->pipe != pipe)<br class="">
      screen->pipe = pipe;<br class="">
@@ -1236,8 +1269,12 @@ swr_update_derived(struct pipe_context *pipe,<br class="">
   }<br class="">
<br class="">
   /* FragmentShader */<br class="">
-   if (ctx->dirty & (SWR_NEW_FS | SWR_NEW_SAMPLER | SWR_NEW_SAMPLER_VIEW<br class="">
-                     | SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {<br class="">
+   if (ctx->dirty & (SWR_NEW_FS |<br class="">
+                     SWR_NEW_VS |<br class="">
+                     SWR_NEW_RASTERIZER |<br class="">
+                     SWR_NEW_SAMPLER |<br class="">
+                     SWR_NEW_SAMPLER_VIEW |<br class="">
+                     SWR_NEW_FRAMEBUFFER)) {<br class="">
      swr_jit_fs_key key;<br class="">
      swr_generate_fs_key(key, ctx, ctx->fs);<br class="">
      auto search = ctx->fs->map.find(key);<br class="">
@@ -1505,7 +1542,7 @@ swr_update_derived(struct pipe_context *pipe,<br class="">
      }<br class="">
   }<br class="">
<br class="">
-   if (ctx->dirty & SWR_NEW_CLIP) {<br class="">
+   if (ctx->dirty & (SWR_NEW_CLIP | SWR_NEW_RASTERIZER | SWR_NEW_VS)) {<br class="">
      // shader exporting clip distances overrides all user clip planes<br class="">
      if (ctx->rasterizer->clip_plane_enable &&<br class="">
          !ctx->vs->info.base.num_written_clipdistance)<br class="">
-- <br class="">
2.7.4<br class="">
<br class="">
_______________________________________________<br class="">
mesa-dev mailing list<br class="">
<a href="mailto:mesa-dev@lists.freedesktop.org" class="">mesa-dev@lists.freedesktop.org</a><br class="">
https://lists.freedesktop.org/mailman/listinfo/mesa-dev<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</body>
</html>