<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>