Any more feedback regarding this?<div><br></div><div>I now don&#39;t have much time to work on it again, but I may find some, so knowing what&#39;s left to do would be nice...<br><br><div class="gmail_quote">On Thu, Aug 4, 2011 at 2:59 PM, Micael Dias <span dir="ltr">&lt;<a href="mailto:kam1kaz3@gmail.com">kam1kaz3@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">---<br>
 src/mesa/SConscript                          |    1 +<br>
 src/mesa/main/fbobject.c                     |   16 +-<br>
 src/mesa/main/fbobject.h                     |    6 +<br>
 src/mesa/sources.mak                         |    1 +<br>
 src/mesa/state_tracker/st_cb_feedback.c      |   21 +-<br>
 src/mesa/state_tracker/st_context.h          |   10 +<br>
 src/mesa/state_tracker/st_draw.h             |   17 +<br>
</div> src/mesa/state_tracker/st_draw_select_emul.c |  490 ++++++++++++++++++++++++++<br>
 8 files changed, 549 insertions(+), 13 deletions(-)<br>
<div><div></div><div class="h5"> create mode 100644 src/mesa/state_tracker/st_draw_select_emul.c<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/main/fbobject.c b/src/mesa/main/fbobject.c<br>
index 82eb7fb..1aea62b 100644<br>
--- a/src/mesa/main/fbobject.c<br>
+++ b/src/mesa/main/fbobject.c<br>
@@ -1560,8 +1560,8 @@ _mesa_IsFramebufferEXT(GLuint framebuffer)<br>
  * (render to texture).  Call ctx-&gt;Driver.RenderTexture() for such<br>
  * attachments.<br>
  */<br>
-static void<br>
-check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<br>
+void<br>
+_mesa_check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<br>
 {<br>
    GLuint i;<br>
    ASSERT(ctx-&gt;Driver.RenderTexture);<br>
@@ -1583,8 +1583,8 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<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>
-static void<br>
-check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<br>
+void<br>
+_mesa_check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)<br>
 {<br>
    if (is_winsys_fbo(fb))<br>
       return; /* can&#39;t render to texture with winsys framebuffers */<br>
@@ -1713,7 +1713,7 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)<br>
       FLUSH_VERTICES(ctx, _NEW_BUFFERS);<br>
<br>
       /* check if old readbuffer was render-to-texture */<br>
-      check_end_texture_render(ctx, oldReadFb);<br>
+      _mesa_check_end_texture_render(ctx, oldReadFb);<br>
<br>
       _mesa_reference_framebuffer(&amp;ctx-&gt;ReadBuffer, newReadFb);<br>
    }<br>
@@ -1723,13 +1723,13 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)<br>
<br>
       /* check if old read/draw buffers were render-to-texture */<br>
       if (!bindReadBuf)<br>
-         check_end_texture_render(ctx, oldReadFb);<br>
+         _mesa_check_end_texture_render(ctx, oldReadFb);<br>
<br>
       if (oldDrawFb != oldReadFb)<br>
-         check_end_texture_render(ctx, oldDrawFb);<br>
+         _mesa_check_end_texture_render(ctx, oldDrawFb);<br>
<br>
       /* check if newly bound framebuffer has any texture attachments */<br>
-      check_begin_texture_render(ctx, newDrawFb);<br>
+      _mesa_check_begin_texture_render(ctx, newDrawFb);<br>
<br>
       _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, newDrawFb);<br>
    }<br>
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h<br>
index 7eb2005..ca6251c 100644<br>
--- a/src/mesa/main/fbobject.h<br>
+++ b/src/mesa/main/fbobject.h<br>
@@ -101,6 +101,12 @@ _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat);<br>
 extern GLenum<br>
 _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat);<br>
<br>
+extern void<br>
+_mesa_check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb);<br>
+<br>
+extern void<br>
+_mesa_check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb);<br>
+<br>
 extern GLboolean GLAPIENTRY<br>
 _mesa_IsRenderbufferEXT(GLuint renderbuffer);<br>
<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>
diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c<br>
index 9b85a39..c96c97c 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; !st-&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_context.h b/src/mesa/state_tracker/st_context.h<br>
index 0a32202..8a8e11a 100644<br>
--- a/src/mesa/state_tracker/st_context.h<br>
+++ b/src/mesa/state_tracker/st_context.h<br>
@@ -207,6 +207,16 @@ struct st_context<br>
<br>
    int32_t draw_stamp;<br>
    int32_t read_stamp;<br>
+<br>
+   /* data related to hw accelerated GL_SELECT */<br>
+   struct gl_selection_emul<br>
+   {<br>
+      GLboolean hw_unsupported;<br>
+      struct gl_framebuffer *fbo;<br>
+      GLuint rb_depth_name;<br>
+      GLuint rb_color_name;<br>
+      void *fs;<br>
+   } select_emul;<br>
 };<br>
<br>
<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>
</div></div>index 0000000..d6bb244<br>
<div class="im">--- /dev/null<br>
+++ b/src/mesa/state_tracker/st_draw_select_emul.c<br>
</div>@@ -0,0 +1,490 @@<br>
<div><div></div><div class="h5">+/**************************************************************************<br>
+ *<br>
+ * Copyright 2011 Micael Dias &lt;kam1kaz3 (at) gmail (dot) com&gt;,<br>
+ *                Pierre-Eric Pelloux-Prayer<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>
+/**<br>
+ * This file contains code that attempts to accelerate GL_SELECT rendering.<br>
+ * It was created with the intent of solving the following bug:<br>
+ *     <a href="https://bugs.freedesktop.org/show_bug.cgi?id=34495" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=34495</a><br>
+ *<br>
+ * This code is a rewritten version of the patch &quot;GL_SELECT hw support v5&quot;<br>
+ * posted by user Pierre-Eric Pelloux-Prayer in the previously mentioned bug.<br>
+ *<br>
+ * In order to test this code, the env. variable MESA_HW_SELECT should be<br>
+ * exported.<br>
+ *<br>
+ * How this algorithm works:<br>
+ * - When in GL_SELECT mode, draw calls are redirected to st_select_draw_func()<br>
+ * which configures states in a way that makes the rendered primitives draw<br>
+ * to a custom FBO that stores depth values (both min and max values) and<br>
+ * emits these values through _mesa_update_hitflag().<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;pipe/p_shader_tokens.h&quot;<br>
+#include &quot;util/u_inlines.h&quot;<br>
+#include &quot;util/u_simple_shaders.h&quot;<br>
+#include &quot;cso_cache/cso_context.h&quot;<br>
+#include &quot;tgsi/tgsi_ureg.h&quot;<br>
+<br>
+#include &quot;draw/draw_private.h&quot;<br>
+#include &quot;draw/draw_context.h&quot;<br>
+<br>
+/**<br>
+ * Custom fragment shader that does nothing but ouput a constant color<br>
+ */<br>
+static void*<br>
+st_select_emul_create_fs(struct gl_context *ctx)<br>
+{<br>
+   struct st_context *st = st_context(ctx);<br>
+   struct pipe_context *pipe = st-&gt;pipe;<br>
+   struct ureg_program *ureg;<br>
+   struct ureg_dst out;<br>
+   struct ureg_src imm;<br>
+<br>
+   ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );<br>
+   if (ureg == NULL)<br>
+      return NULL;<br>
+<br>
+   out = ureg_DECL_output( ureg,<br>
+                           TGSI_SEMANTIC_COLOR,<br>
+                           0 );<br>
+<br>
</div></div>+   imm = ureg_imm4f( ureg, 0.0f, 0.0f, 0.0f, 1.0f );<br>
<div><div></div><div class="h5">+<br>
+   ureg_MOV( ureg, out, imm );<br>
+   ureg_END( ureg );<br>
+<br>
+   return ureg_create_shader_and_destroy( ureg, pipe );<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>
+static void<br>
+st_select_emul_clear_fbo(struct gl_context *ctx)<br>
+{<br>
+   struct st_context *st = st_context(ctx);<br>
+   struct gl_scissor_attrib saved_scissor;<br>
+   struct gl_framebuffer *saved_fbo = NULL;<br>
+   GLfloat clearDepth;<br>
+<br>
+   /* save states */<br>
+   saved_scissor = ctx-&gt;Scissor;<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>
+      /* XXX: needs flushing? */<br>
+      _mesa_check_end_texture_render(ctx, saved_fbo);<br>
+   }<br>
+<br>
+   /* use our fbo */<br>
+   _mesa_check_begin_texture_render(ctx, st-&gt;select_emul.fbo);<br>
+   _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, st-&gt;select_emul.fbo);<br>
+<br>
+   /* update fbo */<br>
+   _mesa_update_framebuffer(ctx);<br>
+<br>
+   /* make sure context is up to date */<br>
+   _mesa_update_state(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>
+   _mesa_check_end_texture_render(ctx, st-&gt;select_emul.fbo);<br>
+   if (saved_fbo) {<br>
+      _mesa_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>
+   ctx-&gt;Scissor = saved_scissor;<br>
+   ctx-&gt;NewState |= _NEW_SCISSOR | _NEW_DEPTH | _NEW_BUFFERS;<br>
+   _mesa_update_state(ctx);<br>
+}<br>
+<br>
+/**<br>
+ * Clean up data<br>
+ */<br>
+static void<br>
+st_select_emul_destroy_fbo(struct gl_context *ctx)<br>
+{<br>
+   struct st_context *st = st_context(ctx);<br>
+   if (st-&gt;select_emul.rb_color_name) {<br>
+      _mesa_DeleteRenderbuffersEXT(1, &amp;st-&gt;select_emul.rb_color_name);<br>
+      st-&gt;select_emul.rb_color_name = 0;<br>
+   }<br>
+   if (st-&gt;select_emul.rb_depth_name) {<br>
+      _mesa_DeleteRenderbuffersEXT(1, &amp;st-&gt;select_emul.rb_depth_name);<br>
+      st-&gt;select_emul.rb_depth_name = 0;<br>
+   }<br>
+   if (st-&gt;select_emul.fbo) {<br>
+      _mesa_DeleteFramebuffersEXT(1, &amp;st-&gt;select_emul.fbo-&gt;Name);<br>
+      _mesa_reference_framebuffer(&amp;st-&gt;select_emul.fbo, NULL);<br>
+   }<br>
+   if (st-&gt;select_emul.fs) {<br>
+      cso_delete_fragment_shader(st-&gt;cso_context, st-&gt;select_emul.fs);<br>
+      st-&gt;select_emul.fs = NULL;<br>
+   }<br>
+}<br>
+<br>
+/**<br>
+ * Create and setup FBO needed for our operations<br>
+ */<br>
+static bool<br>
+st_select_emul_create_fbo(struct gl_context *ctx)<br>
+{<br>
+   GLuint fboName;<br>
+   struct st_context *st = st_context(ctx);<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;st-&gt;select_emul.rb_depth_name);<br>
+   _mesa_GenRenderbuffersEXT(1, &amp;st-&gt;select_emul.rb_color_name);<br>
+<br>
+   /* allocate buffers&#39; memory */<br>
+   _mesa_BindFramebufferEXT(GL_FRAMEBUFFER, fboName);<br>
+   _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, st-&gt;select_emul.rb_depth_name);<br>
+   _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 2, 1);<br>
+   _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, st-&gt;select_emul.rb_color_name);<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,<br>
+                                    GL_RENDERBUFFER,<br>
+                                    st-&gt;select_emul.rb_depth_name);<br>
+   _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                                    GL_RENDERBUFFER,<br>
+                                    st-&gt;select_emul.rb_color_name);<br>
+<br>
+   if (_mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {<br>
+      st_select_emul_destroy_fbo(ctx);<br>
+      return false;<br>
+   }<br>
+<br>
+   _mesa_BindFramebufferEXT(GL_FRAMEBUFFER, 0);<br>
+<br>
+   /* get fbo pointer */<br>
+   st-&gt;select_emul.fbo = _mesa_lookup_framebuffer(ctx, fboName);<br>
+<br>
+   /* create fragment shader */<br>
+   st-&gt;select_emul.fs = st_select_emul_create_fs(ctx);<br>
+<br>
+   /* check fbo pointer validity */<br>
+   if (!st-&gt;select_emul.fbo) {<br>
+      st_select_emul_destroy_fbo(ctx);<br>
+      return false;<br>
+   }<br>
+<br>
+   return true;<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>
+   struct st_context *st = st_context(ctx);<br>
+<br>
+   /* perform an hw caps check once */<br>
+   static bool hw_checked = false;<br>
+   if (!hw_checked) {<br>
+      hw_checked = true;<br>
+      /* XXX: is this a proper way to check for hw support? */<br>
+      if (!ctx-&gt;Driver.ReadPixels ||<br>
+          !ctx-&gt;Driver.DrawPixels ||<br>
+          !ctx-&gt;Driver.NewFramebuffer ||<br>
+          !ctx-&gt;Driver.NewRenderbuffer) {<br>
+         st-&gt;select_emul.hw_unsupported = true;<br>
+         return false;<br>
+      }<br>
+   }<br>
+<br>
+   /* initialize fbo if not yet initialized */<br>
+   if (!st-&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>
+ * Reads into our FBO and emit z-buffer results<br>
+ * called by st_select_draw_func()<br>
+ */<br>
+static void<br>
+st_select_emul_update_hits(struct gl_context *ctx)<br>
+{<br>
+   struct st_context *st = st_context(ctx);<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>
+      _mesa_check_end_texture_render(ctx, saved_fbo);<br>
+   }<br>
+   _mesa_check_begin_texture_render(ctx, st-&gt;select_emul.fbo);<br>
+   _mesa_reference_framebuffer(&amp;ctx-&gt;ReadBuffer, st-&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>
+   _mesa_check_end_texture_render(ctx, st-&gt;select_emul.fbo);<br>
+   if (saved_fbo) {<br>
+      _mesa_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>
+/**<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>
</div></div><div class="im">+   GLboolean saved_scissorEnabled;<br>
+   struct gl_framebuffer *saved_fbo = NULL;<br>
+   struct st_context *st = st_context(ctx);<br>
+   struct pipe_depth_stencil_alpha_state state_depth;<br>
</div>+   struct pipe_viewport_state state_viewport;<br>
<div class="im">+<br>
+   /* save states */<br>
+   if (ctx-&gt;DrawBuffer)<br>
+      _mesa_reference_framebuffer(&amp;saved_fbo, ctx-&gt;DrawBuffer);<br>
+<br>
</div><div class="im">+   saved_scissorEnabled = ctx-&gt;Scissor.Enabled;<br>
+   cso_save_fragment_shader(st-&gt;cso_context);<br>
+   cso_save_depth_stencil_alpha(st-&gt;cso_context);<br>
</div>+   cso_save_viewport(st-&gt;cso_context);<br>
+<br>
+   /* prepare stencil state */<br>
<div class="im">+   memset(&amp;state_depth, 0, sizeof(state_depth));<br>
+   state_depth.depth.enabled = 1;<br>
+   state_depth.depth.writemask = 1;<br>
+<br>
</div>+   /* prepare viewport state */<br>
+   memset(&amp;state_viewport, 0, sizeof(state_viewport));<br>
+   state_viewport.scale[0] = 0.5f * 2.0f * 0.5;<br>
+   state_viewport.scale[1] = 0.5f * 1.0f;<br>
+   state_viewport.scale[2] = 1.0f;<br>
+   state_viewport.scale[3] = 1.0f;<br>
+   state_viewport.translate[1] = 0.5f * 1.0f;<br>
+   state_viewport.translate[2] = 0.0f;<br>
+   state_viewport.translate[3] = 0.0f;<br>
<div class="im">+<br>
+   /* use our custom fragment shader */<br>
+   cso_set_fragment_shader_handle(st-&gt;cso_context, st-&gt;select_emul.fs);<br>
+<br>
+   /* disable scissor */<br>
+   ctx-&gt;Scissor.Enabled = GL_FALSE;<br>
+<br>
+   /* disable old draw fbo */<br>
+   if (saved_fbo)<br>
+      _mesa_check_end_texture_render(ctx, saved_fbo);<br>
+<br>
+   /* use our fbo */<br>
+   _mesa_check_begin_texture_render(ctx, st-&gt;select_emul.fbo);<br>
+   _mesa_reference_framebuffer(&amp;ctx-&gt;DrawBuffer, st-&gt;select_emul.fbo);<br>
+<br>
+   /* update fbo */<br>
+   _mesa_update_framebuffer( ctx );<br>
+<br>
</div>+   /* update context */<br>
+   _mesa_update_state(ctx);<br>
+<br>
+   /* render min-z */<br>
+   {<br>
+      /* specific states */<br>
<div class="im">+      state_depth.depth.func = PIPE_FUNC_LESS;<br>
</div>+      state_viewport.translate[0] = 0.5f * 1.0f + 0.0f;<br>
<div class="im">+<br>
+      cso_set_depth_stencil_alpha(st-&gt;cso_context, &amp;state_depth);<br>
</div>+      cso_set_viewport(st-&gt;cso_context, &amp;state_viewport);<br>
+<br>
+      /* draw */<br>
<div class="im">+      st_draw_vbo(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, min_index, max_index);<br>
+   }<br>
+<br>
+   /* render max-z */<br>
+   {<br>
+      state_depth.depth.func = PIPE_FUNC_GREATER;<br>
</div>+      state_viewport.translate[0] = 0.5f * 1.0f + 1.0f;<br>
<div class="im">+<br>
+      cso_set_depth_stencil_alpha(st-&gt;cso_context, &amp;state_depth);<br>
</div>+      cso_set_viewport(st-&gt;cso_context, &amp;state_viewport);<br>
+<br>
+      /* draw */<br>
<div class="im">+      st_draw_vbo(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, min_index, max_index);<br>
+   }<br>
+<br>
+   /* XXX: needs flushing? */<br>
+<br>
+   /* restore states */<br>
+   cso_restore_fragment_shader(st-&gt;cso_context);<br>
+   cso_restore_depth_stencil_alpha(st-&gt;cso_context);<br>
</div>+   cso_restore_viewport(st-&gt;cso_context);<br>
<div class="im">+   ctx-&gt;Scissor.Enabled = saved_scissorEnabled;<br>
+   _mesa_check_end_texture_render(ctx, st-&gt;select_emul.fbo);<br>
+   if (saved_fbo) {<br>
+      _mesa_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>
</div><div><div></div><div class="h5">+   _mesa_update_state(ctx);<br>
+<br>
+   /* update hits */<br>
+   st_select_emul_update_hits(ctx);<br>
+}<br>
+<br>
--<br>
1.7.6<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>Micael Dias<br>
</div>