<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="">
<div class="">Looks good..</div>
<div class=""><br class="">
</div>
Reviewed-By: George Kyriazis <<a href="mailto:george.kyriazis@intel.com" class="">george.kyriazis@intel.com</a>>
<div class=""><br class="">
<div>
<blockquote type="cite" class="">
<div class="">On Nov 8, 2017, at 6:39 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="">State validation is performed during clear and draw calls.  Validation<br class="">
during clear was still accessing vertex buffer state.  When the currently<br class="">
set vertex buffers are client arrays, this could lead to accessing freed<br class="">
memory.  Such is the case with the VMD application.<br class="">
<br class="">
Previously, vertex buffer validation depended on a dirty bit or the<br class="">
draw info indicating an indexed draw.  This required special handling for<br class="">
clears.  But, vertex buffer validation still occurred which was unnecessary<br class="">
and wrong.<br class="">
<br class="">
Now, only minimal validation is performed during clear, deferring the<br class="">
remainder to the next draw.  And, by setting the dirty bit in swr_draw_vbo<br class="">
for indexed draws, vertex buffer validation is only dependent upon a<br class="">
single dirty bit.<br class="">
<br class="">
This fixes a bug exposed by the VMD application when changing models.<br class="">
---<br class="">
src/gallium/drivers/swr/swr_draw.cpp  |  7 ++++++-<br class="">
src/gallium/drivers/swr/swr_state.cpp | 35 +++++++++++++++++++----------------<br class="">
2 files changed, 25 insertions(+), 17 deletions(-)<br class="">
<br class="">
diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp<br class="">
index 57660c7464..a94cdd6da0 100644<br class="">
--- a/src/gallium/drivers/swr/swr_draw.cpp<br class="">
+++ b/src/gallium/drivers/swr/swr_draw.cpp<br class="">
@@ -52,7 +52,12 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)<br class="">
      return;<br class="">
   }<br class="">
<br class="">
-   /* Update derived state, pass draw info to update function */<br class="">
+   /* If indexed draw, force vertex validation since index buffer comes<br class="">
+    * from draw info. */<br class="">
+   if (info->index_size)<br class="">
+      ctx->dirty |= SWR_NEW_VERTEX;<br class="">
+<br class="">
+   /* Update derived state, pass draw info to update function. */<br class="">
   swr_update_derived(pipe, info);<br class="">
<br class="">
   swr_update_draw_context(ctx);<br class="">
diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp<br class="">
index c6da4fcb8e..4530d377ee 100644<br class="">
--- a/src/gallium/drivers/swr/swr_state.cpp<br class="">
+++ b/src/gallium/drivers/swr/swr_state.cpp<br class="">
@@ -1204,11 +1204,6 @@ swr_update_derived(struct pipe_context *pipe,<br class="">
      ctx->api.pfnSwrSetRastState(ctx->swrContext, rastState);<br class="">
   }<br class="">
<br class="">
-   /* Scissor */<br class="">
-   if (ctx->dirty & SWR_NEW_SCISSOR) {<br class="">
-      ctx->api.pfnSwrSetScissorRects(ctx->swrContext, 1, &ctx->swr_scissor);<br class="">
-   }<br class="">
-<br class="">
   /* Viewport */<br class="">
   if (ctx->dirty & (SWR_NEW_VIEWPORT | SWR_NEW_FRAMEBUFFER<br class="">
                     | SWR_NEW_RASTERIZER)) {<br class="">
@@ -1249,18 +1244,26 @@ swr_update_derived(struct pipe_context *pipe,<br class="">
      ctx->api.pfnSwrSetViewports(ctx->swrContext, 1, vp, vpm);<br class="">
   }<br class="">
<br class="">
-   /* Set vertex & index buffers<br class="">
-    * (using draw info if called by swr_draw_vbo)<br class="">
-    * If indexed draw, revalidate since index buffer comes from<br class="">
-    * pipe_draw_info.<br class="">
-    */<br class="">
-   if (ctx->dirty & SWR_NEW_VERTEX ||<br class="">
-      (p_draw_info && p_draw_info->index_size)) {<br class="">
+   /* When called from swr_clear (p_draw_info = null), render targets,<br class="">
+    * rasterState and viewports (dependent on render targets) are the only<br class="">
+    * necessary validation.  Defer remaining validation by setting<br class="">
+    * post_update_dirty_flags and clear all dirty flags.  BackendState is<br class="">
+    * still unconditionally validated below */<br class="">
+   if (!p_draw_info) {<br class="">
+      post_update_dirty_flags = ctx->dirty & ~(SWR_NEW_FRAMEBUFFER |<br class="">
+                                               SWR_NEW_RASTERIZER |<br class="">
+                                               SWR_NEW_VIEWPORT);<br class="">
+      ctx->dirty = 0;<br class="">
+   }<br class="">
+<br class="">
+   /* Scissor */<br class="">
+   if (ctx->dirty & SWR_NEW_SCISSOR) {<br class="">
+      ctx->api.pfnSwrSetScissorRects(ctx->swrContext, 1, &ctx->swr_scissor);<br class="">
+   }<br class="">
<br class="">
-      /* If being called by swr_draw_vbo, copy draw details */<br class="">
-      struct pipe_draw_info info = {0};<br class="">
-      if (p_draw_info)<br class="">
-         info = *p_draw_info;<br class="">
+   /* Set vertex & index buffers */<br class="">
+   if (ctx->dirty & SWR_NEW_VERTEX) {<br class="">
+      const struct pipe_draw_info &info = *p_draw_info;<br class="">
<br class="">
      /* vertex buffers */<br class="">
      SWR_VERTEX_BUFFER_STATE swrVertexBuffers[PIPE_MAX_ATTRIBS];<br class="">
-- <br class="">
2.11.0<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>