Might want to fix the copyright message at the top of source file. ;)<br><br>
<div class="gmail_quote">On Tue, Aug 2, 2011 at 8:37 AM, Micael Dias <span dir="ltr">&lt;<a href="mailto:kam1kaz3@gmail.com">kam1kaz3@gmail.com</a>&gt;</span> wrote:<br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">---<br> src/mesa/main/mtypes.h                       |    7 +<br> src/mesa/state_tracker/st_cb_feedback.c      |   21 +-<br>
 src/mesa/state_tracker/st_draw.h             |   17 +<br> src/mesa/state_tracker/st_draw_select_emul.c |  463 ++++++++++++++++++++++++++<br> src/mesa/SConscript                          |    1 +<br> src/mesa/sources.mak                         |    1 +<br>
 6 files changed, 505 insertions(+), 5 deletions(-)<br> create mode 100644 src/mesa/state_tracker/st_draw_select_emul.c<br><br>diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h<br>index b881183..10222d8 100644<br>
--- a/src/mesa/main/mtypes.h<br>+++ b/src/mesa/main/mtypes.h<br>@@ -1721,6 +1721,13 @@ struct gl_selection<br>   GLboolean HitFlag;  /**&lt; hit flag */<br>   GLfloat HitMinZ;    /**&lt; minimum hit depth */<br>   GLfloat HitMaxZ;    /**&lt; maximum hit depth */<br>
+   struct gl_selection_emul /* data related to hw accelerated GL_SELECT */<br>+   {<br>+      GLboolean hw_unsupported;<br>+      struct gl_framebuffer *fbo;<br>+      GLuint renderBuffer_depth;<br>+      GLuint renderBuffer_color;<br>
+   } emul;<br> };<br><br><br>diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c<br>index 9b85a39..9382895 100644<br>--- a/src/mesa/state_tracker/st_cb_feedback.c<br>+++ b/src/mesa/state_tracker/st_cb_feedback.c<br>
@@ -276,17 +276,28 @@ st_RenderMode(struct gl_context *ctx, GLenum newMode )<br> {<br>   struct st_context *st = st_context(ctx);<br>   struct draw_context *draw = st-&gt;draw;<br>+   bool hw_acc_path = _mesa_getenv(&quot;MESA_HW_SELECT&quot;) &amp;&amp; !ctx-&gt;Select.emul.hw_unsupported;<br>
<br>   if (newMode == GL_RENDER) {<br>      /* restore normal VBO draw function */<br>      vbo_set_draw_func(ctx, st_draw_vbo);<br>   }<br>   else if (newMode == GL_SELECT) {<br>-      if (!st-&gt;selection_stage)<br>-         st-&gt;selection_stage = draw_glselect_stage(ctx, draw);<br>
-      draw_set_rasterize_stage(draw, st-&gt;selection_stage);<br>-      /* Plug in new vbo draw function */<br>-      vbo_set_draw_func(ctx, st_feedback_draw_vbo);<br>+      if (hw_acc_path) {<br>+         if (st_select_emul_begin(ctx)) {<br>
+            vbo_set_draw_func(ctx, st_select_draw_func);<br>+         }<br>+         else {<br>+            hw_acc_path = false;<br>+         }<br>+      }<br>+      if (!hw_acc_path) {<br>+         if (!st-&gt;selection_stage)<br>
+            st-&gt;selection_stage = draw_glselect_stage(ctx, draw);<br>+         draw_set_rasterize_stage(draw, st-&gt;selection_stage);<br>+         /* Plug in new vbo draw function */<br>+         vbo_set_draw_func(ctx, st_feedback_draw_vbo);<br>
+      }<br>   }<br>   else {<br>      if (!st-&gt;feedback_stage)<br>diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h<br>index a7b50ce..d27e321 100644<br>--- a/src/mesa/state_tracker/st_draw.h<br>
+++ b/src/mesa/state_tracker/st_draw.h<br>@@ -87,5 +87,22 @@ pointer_to_offset(const void *ptr)<br>   return (unsigned) (((unsigned long) ptr) &amp; 0xffffffffUL);<br> }<br><br>+/* Functions used by the hw accelerated GL_SELECT emulator<br>
+ */<br>+extern bool<br>+st_select_emul_begin(struct gl_context *ctx);<br>+<br>+extern void<br>+st_select_emul_end(struct gl_context *ctx);<br>+<br>+extern void<br>+st_select_draw_func(struct gl_context *ctx,<br>+            const struct gl_client_array **arrays,<br>
+            const struct _mesa_prim *prims,<br>+            GLuint nr_prims,<br>+            const struct _mesa_index_buffer *ib,<br>+            GLboolean index_bounds_valid,<br>+            GLuint min_index,<br>+            GLuint max_index);<br>
<br> #endif<br>diff --git a/src/mesa/state_tracker/st_draw_select_emul.c b/src/mesa/state_tracker/st_draw_select_emul.c<br>new file mode 100644<br>index 0000000..78065dd<br>--- /dev/null<br>+++ b/src/mesa/state_tracker/st_draw_select_emul.c<br>
@@ -0,0 +1,463 @@<br>+/**************************************************************************<br>+ *<br>+ * Copyright xxxxxxxxxxxxxxxx.<br>+ * All Rights Reserved.<br>+ *<br>+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the<br>+ * &quot;Software&quot;), to deal in the Software without restriction, including<br>+ * without limitation the rights to use, copy, modify, merge, publish,<br>
+ * distribute, sub license, and/or sell copies of the Software, and to<br>+ * permit persons to whom the Software is furnished to do so, subject to<br>+ * the following conditions:<br>+ *<br>+ * The above copyright notice and this permission notice (including the<br>
+ * next paragraph) shall be included in all copies or substantial portions<br>+ * of the Software.<br>+ *<br>+ * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS<br>+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<br>
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.<br>+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR<br>+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,<br>
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE<br>+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br>+ *<br>+ **************************************************************************/<br>
+<br>+#include &quot;main/imports.h&quot;<br>+#include &quot;main/image.h&quot;<br>+#include &quot;main/macros.h&quot;<br>+#include &quot;main/mfeatures.h&quot;<br>+#include &quot;main/hash.h&quot;<br>+<br>+#include &quot;main/context.h&quot;<br>
+#include &quot;main/enable.h&quot;<br>+#include &quot;main/fbobject.h&quot;<br>+#include &quot;main/depth.h&quot;<br>+#include &quot;main/state.h&quot;<br>+#include &quot;main/scissor.h&quot;<br>+#include &quot;main/viewport.h&quot;<br>
+#include &quot;main/framebuffer.h&quot;<br>+#include &quot;main/feedback.h&quot;<br>+<br>+#include &quot;vbo/vbo.h&quot;<br>+<br>+#include &quot;st_context.h&quot;<br>+#include &quot;st_atom.h&quot;<br>+#include &quot;st_cb_bufferobjects.h&quot;<br>
+#include &quot;st_draw.h&quot;<br>+#include &quot;st_program.h&quot;<br>+#include &quot;st_texture.h&quot;<br>+#include &quot;st_cb_readpixels.h&quot;<br>+<br>+#include &quot;pipe/p_context.h&quot;<br>+#include &quot;pipe/p_defines.h&quot;<br>
+#include &quot;pipe/p_state.h&quot;<br>+#include &quot;pipe/p_format.h&quot;<br>+#include &quot;util/u_inlines.h&quot;<br>+<br>+#include &quot;draw/draw_private.h&quot;<br>+#include &quot;draw/draw_context.h&quot;<br>+<br>
+bool<br>+st_select_emul_create_fbo(struct gl_context *ctx);<br>+<br>+void<br>+st_select_emul_destroy_fbo(struct gl_context *ctx);<br>+<br>+void<br>+st_select_emul_check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb);<br>
+<br>+void<br>+st_select_emul_check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb);<br>+<br>+void<br>+st_select_emul_clear_fbo(struct gl_context *ctx);<br>+<br>+void<br>+st_select_emul_update_hits(struct gl_context *ctx);<br>
+<br>+/**<br>+ * Check if any of the attachments of the given framebuffer are textures<br>+ * (render to texture).  Call ctx-&gt;Driver.RenderTexture() for such<br>+ * attachments.<br>+ */<br>+void<br>+st_select_emul_check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<br>
+{<br>+   GLuint i;<br>+   ASSERT(ctx-&gt;Driver.RenderTexture);<br>+<br>+   if (fb==0)<br>+      return; /* can&#39;t render to texture with winsys framebuffers */<br>+<br>+   for (i = 0; i &lt; BUFFER_COUNT; i++) {<br>+      struct gl_renderbuffer_attachment *att = fb-&gt;Attachment + i;<br>
+      if (att-&gt;Texture &amp;&amp; _mesa_get_attachment_teximage(att)) {<br>+         ctx-&gt;Driver.RenderTexture(ctx, fb, att);<br>+      }<br>+   }<br>+}<br>+<br>+<br>+/**<br>+ * Examine all the framebuffer&#39;s attachments to see if any are textures.<br>
+ * If so, call ctx-&gt;Driver.FinishRenderTexture() for each texture to<br>+ * notify the device driver that the texture image may have changed.<br>+ */<br>+void<br>+st_select_emul_check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<br>
+{<br>+   if (fb==0)<br>+      return; /* can&#39;t render to texture with winsys framebuffers */<br>+<br>+   if (ctx-&gt;Driver.FinishRenderTexture) {<br>+      GLuint i;<br>+      for (i = 0; i &lt; BUFFER_COUNT; i++) {<br>
+         struct gl_renderbuffer_attachment *att = fb-&gt;Attachment + i;<br>+         if (att-&gt;Texture &amp;&amp; att-&gt;Renderbuffer) {<br>+            ctx-&gt;Driver.FinishRenderTexture(ctx, att);<br>+         }<br>
+      }<br>+   }<br>+}<br>+<br>+/**<br>+ * Create and setup FBO needed for our operations<br>+ */<br>+bool<br>+st_select_emul_create_fbo(struct gl_context *ctx)<br>+{<br>+   GLuint fboName;<br>+<br>+   /* make sure we don&#39;t leak memory */<br>
+   st_select_emul_destroy_fbo(ctx);<br>+<br>+   /* create buffer names */<br>+   _mesa_GenFramebuffersEXT(1, &amp;fboName);<br>+   _mesa_GenRenderbuffersEXT(1, &amp;ctx-&gt;Select.emul.renderBuffer_depth);<br>+   _mesa_GenRenderbuffersEXT(1, &amp;ctx-&gt;Select.emul.renderBuffer_color);<br>
+<br>+   /* allocate buffers&#39; memory */<br>+   _mesa_BindFramebufferEXT(GL_FRAMEBUFFER, fboName);<br>+   _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, ctx-&gt;Select.emul.renderBuffer_depth);<br>+   _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 2, 1);<br>
+   _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, ctx-&gt;Select.emul.renderBuffer_color);<br>+   _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 2, 1);<br>+   _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, 0);<br>+<br>+   /* setup fbo */<br>
+   _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ctx-&gt;Select.emul.renderBuffer_depth);<br>+   _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ctx-&gt;Select.emul.renderBuffer_color);<br>
+<br>+   if( _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )<br>+      return false;<br>+<br>+   _mesa_BindFramebufferEXT(GL_FRAMEBUFFER, 0);<br>+<br>+   /* get fbo pointer */<br>+   ctx-&gt;Select.emul.fbo = _mesa_lookup_framebuffer(ctx, fboName);<br>
+<br>+   return true;<br>+}<br>+<br>+/**<br>+ * Clean up data<br>+ */<br>+void<br>+st_select_emul_destroy_fbo(struct gl_context *ctx)<br>+{<br>+   if( ctx-&gt;Select.emul.renderBuffer_color ) {<br>+      _mesa_DeleteRenderbuffersEXT( 1, &amp;ctx-&gt;Select.emul.renderBuffer_color );<br>
+      ctx-&gt;Select.emul.renderBuffer_color = 0;<br>+   }<br>+   if( ctx-&gt;Select.emul.renderBuffer_depth ) {<br>+      _mesa_DeleteRenderbuffersEXT( 1, &amp;ctx-&gt;Select.emul.renderBuffer_depth );<br>+      ctx-&gt;Select.emul.renderBuffer_depth = 0;<br>
+   }<br>+   if( ctx-&gt;Select.emul.fbo ) {<br>+      _mesa_DeleteFramebuffersEXT( 1, &amp;ctx-&gt;Select.emul.fbo-&gt;Name );<br>+      _mesa_reference_framebuffer( &amp;ctx-&gt;Select.emul.fbo, NULL );<br>+   }<br>+}<br>
+<br>+/**<br>+ * Called when entering GL_SELECT mode.<br>+ * This function initializes our private data and clears<br>+ * depth so that the next draw call will have it ready.<br>+ */<br>+bool<br>+st_select_emul_begin(struct gl_context *ctx)<br>
+{<br>+   /* TODO: Check for hardware support and fill<br>+   ctx-&gt;Select.emul.hw_unsupported accordingly */<br>+<br>+   /* initialize fbo if not yet initialized */<br>+   if (!ctx-&gt;Select.emul.fbo) {<br>+      if (!st_select_emul_create_fbo(ctx)) {<br>
+         return false;<br>+      }<br>+   }<br>+<br>+   /* clear FBO */<br>+   st_select_emul_clear_fbo(ctx);<br>+<br>+   return true;<br>+}<br>+<br>+void<br>+st_select_emul_end(struct gl_context *ctx)<br>+{<br>+   st_select_emul_destroy_fbo(ctx);<br>
+}<br>+<br>+/**<br>+ * Helper function to change depth state<br>+ */<br>+static void<br>+select_change_depth_state(struct gl_context *ctx, GLenum func, GLboolean mask, GLboolean test) {<br>+   /* depth function */<br>+   if (ctx-&gt;Depth.Func != func) {<br>
+      ctx-&gt;NewState |= _NEW_DEPTH;<br>+      ctx-&gt;Depth.Func = func;<br>+<br>+      if (ctx-&gt;Driver.DepthFunc)<br>+         ctx-&gt;Driver.DepthFunc( ctx, func );<br>+   }<br>+<br>+   /* depth mask */<br>+   if (ctx-&gt;Depth.Mask != mask) {<br>
+      ctx-&gt;NewState |= _NEW_DEPTH;<br>+      ctx-&gt;Depth.Mask = mask;<br>+<br>+      if (ctx-&gt;Driver.DepthMask)<br>+         ctx-&gt;Driver.DepthMask( ctx, mask );<br>+   }<br>+<br>+   /* depth test */<br>+   if (ctx-&gt;Depth.Test != test) {<br>
+      ctx-&gt;NewState |= _NEW_DEPTH;<br>+      ctx-&gt;Depth.Test = test;<br>+   }<br>+}<br>+<br>+/**<br>+ * Clears the depth values of our FBO by setting the<br>+ * 1st pixel to 1.0f and the 2nd to 0.0f<br>+ */<br>+void<br>
+st_select_emul_clear_fbo(struct gl_context *ctx)<br>+{<br>+   struct gl_scissor_attrib saved_scissor;<br>+   struct gl_framebuffer *saved_fbo = NULL;<br>+   GLfloat clearDepth;<br>+<br>+   /* save states */<br>+   memcpy(&amp;saved_scissor, &amp;ctx-&gt;Scissor, sizeof(struct gl_scissor_attrib));<br>
+   if (ctx-&gt;DrawBuffer) {<br>+      _mesa_reference_framebuffer( &amp;saved_fbo, ctx-&gt;DrawBuffer );<br>+   }<br>+   clearDepth = ctx-&gt;Depth.Clear;<br>+<br>+   /* hack needed because Clear does nothing if render mode != GL_RENDER */<br>
+   ctx-&gt;RenderMode = GL_RENDER;<br>+<br>+   /* disable old draw fbo */<br>+   if (saved_fbo)<br>+   {<br>+      /* XXX: needs flushing? */<br>+      st_select_emul_check_end_texture_render(ctx, saved_fbo);<br>+   }<br>
+<br>+   /* use our fbo */<br>+   st_select_emul_check_begin_texture_render(ctx, ctx-&gt;Select.emul.fbo);<br>+   _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, ctx-&gt;Select.emul.fbo);<br>+<br>+   /* update fbo */<br>
+   _mesa_update_framebuffer( ctx );<br>+<br>+   /* enable scissor */<br>+   ctx-&gt;Scissor.Enabled = GL_TRUE;<br>+<br>+   /* clear min-Z */<br>+   ctx-&gt;Scissor.X = 0;<br>+   ctx-&gt;Scissor.Y = 0;<br>+   ctx-&gt;Scissor.Width = 1;<br>
+   ctx-&gt;Scissor.Height = 1;<br>+   ctx-&gt;Depth.Clear = 1.0f;<br>+   if (ctx-&gt;Driver.ClearDepth)<br>+      (*ctx-&gt;Driver.ClearDepth)( ctx, ctx-&gt;Depth.Clear );<br>+   ctx-&gt;NewState |= _NEW_SCISSOR | _NEW_DEPTH | _NEW_BUFFERS;<br>
+   _mesa_update_state( ctx );<br>+   ctx-&gt;Driver.Clear(ctx, BUFFER_BIT_DEPTH);<br>+<br>+   /* clear max-Z */<br>+   ctx-&gt;Scissor.X = 1;<br>+   ctx-&gt;Scissor.Y = 0;<br>+   ctx-&gt;Scissor.Width = 1;<br>+   ctx-&gt;Scissor.Height = 1;<br>
+   ctx-&gt;Depth.Clear = 0.0f;<br>+   if (ctx-&gt;Driver.ClearDepth)<br>+      (*ctx-&gt;Driver.ClearDepth)( ctx, ctx-&gt;Depth.Clear );<br>+   ctx-&gt;NewState |= _NEW_SCISSOR | _NEW_DEPTH;<br>+   _mesa_update_state( ctx );<br>
+   ctx-&gt;Driver.Clear(ctx, BUFFER_BIT_DEPTH);<br>+<br>+   /* restore states */<br>+   st_select_emul_check_end_texture_render(ctx, ctx-&gt;Select.emul.fbo);<br>+   if (saved_fbo) {<br>+      st_select_emul_check_begin_texture_render(ctx, saved_fbo);<br>
+      _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, saved_fbo);<br>+      _mesa_reference_framebuffer(&amp;saved_fbo, NULL);<br>+   }<br>+   else<br>+      _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, NULL);<br>
+<br>+   ctx-&gt;RenderMode = GL_SELECT;<br>+   ctx-&gt;Depth.Clear = clearDepth;<br>+   if (ctx-&gt;Driver.ClearDepth)<br>+      (*ctx-&gt;Driver.ClearDepth)( ctx, ctx-&gt;Depth.Clear );<br>+   memcpy(&amp;ctx-&gt;Scissor, &amp;saved_scissor, sizeof(struct gl_scissor_attrib));<br>
+   ctx-&gt;NewState |= _NEW_SCISSOR | _NEW_DEPTH | _NEW_BUFFERS;<br>+   _mesa_update_state( ctx );<br>+}<br>+<br>+/**<br>+ * Plug in draw function to draw in GL_SELECT mode.<br>+ * This function does the following steps:<br>
+ *   1) render into the 1st pixel of our FBO with depth state<br>+ *      configured so that we get the lowest Z values<br>+ *   2) render into the 2nd pixel of our FBO with depth state<br>+ *      configured so that we get the highest Z values<br>
+ *   3) calls st_select_emul_update_hits() to emit results<br>+ */<br>+void<br>+st_select_draw_func(struct gl_context *ctx,<br>+            const struct gl_client_array **arrays,<br>+            const struct _mesa_prim *prims,<br>
+            GLuint nr_prims,<br>+            const struct _mesa_index_buffer *ib,<br>+            GLboolean index_bounds_valid,<br>+            GLuint min_index,<br>+            GLuint max_index)<br>+{<br>+   struct gl_depthbuffer_attrib saved_depth;<br>
+   struct gl_viewport_attrib saved_viewport;<br>+   GLboolean saved_scissorEnabled;<br>+   struct gl_framebuffer *saved_fbo = NULL;<br>+   struct st_context *st = st_context(ctx);<br>+   struct pipe_context *pipe = st-&gt;pipe;<br>
+   struct pipe_fence_handle *fence;<br>+<br>+   /* save states */<br>+   if (ctx-&gt;DrawBuffer)<br>+      _mesa_reference_framebuffer(&amp;saved_fbo, ctx-&gt;DrawBuffer);<br>+   memcpy(&amp;saved_depth, &amp;ctx-&gt;Depth, sizeof(struct gl_depthbuffer_attrib));<br>
+   memcpy(&amp;saved_viewport, &amp;ctx-&gt;Viewport, sizeof(struct gl_viewport_attrib));<br>+   saved_scissorEnabled = ctx-&gt;Scissor.Enabled;<br>+<br>+   /* disable scissor */<br>+   ctx-&gt;Scissor.Enabled = GL_FALSE;<br>
+<br>+   /* disable old draw fbo */<br>+   if (saved_fbo)<br>+      st_select_emul_check_end_texture_render(ctx, saved_fbo);<br>+<br>+   /* use our fbo */<br>+   st_select_emul_check_begin_texture_render(ctx, ctx-&gt;Select.emul.fbo);<br>
+   _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, ctx-&gt;Select.emul.fbo);<br>+<br>+   /* update fbo */<br>+   _mesa_update_framebuffer( ctx );<br>+<br>+   /* render min-z */<br>+   select_change_depth_state(ctx, GL_LESS, GL_TRUE, GL_TRUE);<br>
+   _mesa_set_viewport(ctx,<br>+                      0, 0,<br>+                      1, 1);<br>+   _mesa_update_state(ctx);<br>+   st_draw_vbo(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, min_index, max_index);<br>
+<br>+   /* render max-z */<br>+   select_change_depth_state(ctx, GL_GREATER, GL_TRUE, GL_TRUE);<br>+   _mesa_set_viewport(ctx,<br>+                      1, 0,<br>+                      1, 1);<br>+   _mesa_update_state(ctx);<br>
+   st_draw_vbo(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, min_index, max_index);<br>+<br>+   /* XXX: needs flushing? */<br>+<br>+   /* restore states */<br>+   ctx-&gt;Scissor.Enabled = saved_scissorEnabled;<br>
+   select_change_depth_state(ctx, saved_depth.Func, saved_depth.Mask, saved_depth.Test);<br>+   st_select_emul_check_end_texture_render(ctx, ctx-&gt;Select.emul.fbo);<br>+   if (saved_fbo) {<br>+      st_select_emul_check_begin_texture_render(ctx, saved_fbo);<br>
+      _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, saved_fbo);<br>+      _mesa_reference_framebuffer(&amp;saved_fbo, NULL);<br>+   }<br>+   else<br>+      _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, NULL);<br>
+   _mesa_set_viewport(ctx, saved_viewport.X, saved_viewport.Y, saved_viewport.Width, saved_viewport.Height);<br>+   _mesa_update_state(ctx);<br>+<br>+   /* update hits */<br>+   st_select_emul_update_hits(ctx);<br>+}<br>
+<br>+/**<br>+ * Reads into our FBO and emit z-buffer results<br>+ * called by st_select_draw_func()<br>+ */<br>+void<br>+st_select_emul_update_hits(struct gl_context *ctx)<br>+{<br>+   struct gl_framebuffer *saved_fbo = NULL;<br>
+   float zData[2];<br>+<br>+   /* set state */<br>+   if (ctx-&gt;ReadBuffer) {<br>+      _mesa_reference_framebuffer(&amp;saved_fbo, ctx-&gt;ReadBuffer);<br>+      st_select_emul_check_end_texture_render(ctx, saved_fbo);<br>
+   }<br>+   st_select_emul_check_begin_texture_render(ctx, ctx-&gt;Select.emul.fbo);<br>+   _mesa_reference_framebuffer(&amp;ctx-&gt;ReadBuffer, ctx-&gt;Select.emul.fbo);<br>+<br>+   /* update fbo */<br>+   _mesa_update_framebuffer( ctx );<br>
+<br>+   /* update state */<br>+   ctx-&gt;NewState |= _NEW_BUFFERS;<br>+   _mesa_update_state( ctx );<br>+<br>+   /* read pixels */<br>+   ctx-&gt;Driver.ReadPixels( ctx, 0, 0, 2, 1,<br>+                           GL_DEPTH_COMPONENT, GL_FLOAT,<br>
+                           &amp;ctx-&gt;Pack, (void*)zData );<br>+<br>+   /* emit z-buffer results */<br>+   if (zData[0] != 1.0f)<br>+      _mesa_update_hitflag( ctx, zData[0] );<br>+   if (zData[1] != 0.0f)<br>+      _mesa_update_hitflag( ctx, zData[1] );<br>
+<br>+   /* clear FBO */<br>+   st_select_emul_clear_fbo(ctx);<br>+<br>+   /* restore state */<br>+   st_select_emul_check_end_texture_render(ctx, ctx-&gt;Select.emul.fbo);<br>+   if (saved_fbo) {<br>+      st_select_emul_check_begin_texture_render(ctx, saved_fbo);<br>
+      _mesa_reference_framebuffer(&amp;ctx-&gt;ReadBuffer, saved_fbo);<br>+      _mesa_reference_framebuffer(&amp;saved_fbo, NULL);<br>+   }<br>+   else<br>+      _mesa_reference_framebuffer(&amp;ctx-&gt;ReadBuffer, NULL);<br>
+<br>+   /* update state */<br>+   ctx-&gt;NewState |= _NEW_BUFFERS;<br>+   _mesa_update_state( ctx );<br>+}<br>+<br>diff --git a/src/mesa/SConscript b/src/mesa/SConscript<br>index 24e2155..288b162 100644<br>--- a/src/mesa/SConscript<br>
+++ b/src/mesa/SConscript<br>@@ -262,6 +262,7 @@ statetracker_sources = [<br>    &#39;state_tracker/st_debug.c&#39;,<br>    &#39;state_tracker/st_draw.c&#39;,<br>    &#39;state_tracker/st_draw_feedback.c&#39;,<br>+    &#39;state_tracker/st_draw_select_emul.c&#39;,<br>
    &#39;state_tracker/st_extensions.c&#39;,<br>    &#39;state_tracker/st_format.c&#39;,<br>    &#39;state_tracker/st_gen_mipmap.c&#39;,<br>diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak<br>index 4b2ec08..9af4079 100644<br>
--- a/src/mesa/sources.mak<br>+++ b/src/mesa/sources.mak<br>@@ -229,6 +229,7 @@ STATETRACKER_SOURCES = \<br>       state_tracker/st_debug.c \<br>       state_tracker/st_draw.c \<br>       state_tracker/st_draw_feedback.c \<br>
+       state_tracker/st_draw_select_emul.c \<br>       state_tracker/st_extensions.c \<br>       state_tracker/st_format.c \<br>       state_tracker/st_gen_mipmap.c \<br><font color="#888888">--<br>1.7.6<br><br>_______________________________________________<br>
mesa-dev mailing list<br><a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br><a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></blockquote></div><br>