Any more feedback regarding this? I now don't have much time to work on it again, but I may find some, so knowing what's left to do would be nice...
On Thu, Aug 4, 2011 at 2:59 PM, Micael Dias <kam1k...@gmail.com> wrote: > --- > src/mesa/SConscript | 1 + > src/mesa/main/fbobject.c | 16 +- > src/mesa/main/fbobject.h | 6 + > src/mesa/sources.mak | 1 + > src/mesa/state_tracker/st_cb_feedback.c | 21 +- > src/mesa/state_tracker/st_context.h | 10 + > src/mesa/state_tracker/st_draw.h | 17 + > src/mesa/state_tracker/st_draw_select_emul.c | 490 > ++++++++++++++++++++++++++ > 8 files changed, 549 insertions(+), 13 deletions(-) > create mode 100644 src/mesa/state_tracker/st_draw_select_emul.c > > diff --git a/src/mesa/SConscript b/src/mesa/SConscript > index 24e2155..288b162 100644 > --- a/src/mesa/SConscript > +++ b/src/mesa/SConscript > @@ -262,6 +262,7 @@ statetracker_sources = [ > 'state_tracker/st_debug.c', > 'state_tracker/st_draw.c', > 'state_tracker/st_draw_feedback.c', > + 'state_tracker/st_draw_select_emul.c', > 'state_tracker/st_extensions.c', > 'state_tracker/st_format.c', > 'state_tracker/st_gen_mipmap.c', > diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c > index 82eb7fb..1aea62b 100644 > --- a/src/mesa/main/fbobject.c > +++ b/src/mesa/main/fbobject.c > @@ -1560,8 +1560,8 @@ _mesa_IsFramebufferEXT(GLuint framebuffer) > * (render to texture). Call ctx->Driver.RenderTexture() for such > * attachments. > */ > -static void > -check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer > *fb) > +void > +_mesa_check_begin_texture_render(struct gl_context *ctx, struct > gl_framebuffer *fb) > { > GLuint i; > ASSERT(ctx->Driver.RenderTexture); > @@ -1583,8 +1583,8 @@ check_begin_texture_render(struct gl_context *ctx, > struct gl_framebuffer *fb) > * If so, call ctx->Driver.FinishRenderTexture() for each texture to > * notify the device driver that the texture image may have changed. > */ > -static void > -check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer > *fb) > +void > +_mesa_check_end_texture_render(struct gl_context *ctx, struct > gl_framebuffer *fb) > { > if (is_winsys_fbo(fb)) > return; /* can't render to texture with winsys framebuffers */ > @@ -1713,7 +1713,7 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint > framebuffer) > FLUSH_VERTICES(ctx, _NEW_BUFFERS); > > /* check if old readbuffer was render-to-texture */ > - check_end_texture_render(ctx, oldReadFb); > + _mesa_check_end_texture_render(ctx, oldReadFb); > > _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb); > } > @@ -1723,13 +1723,13 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint > framebuffer) > > /* check if old read/draw buffers were render-to-texture */ > if (!bindReadBuf) > - check_end_texture_render(ctx, oldReadFb); > + _mesa_check_end_texture_render(ctx, oldReadFb); > > if (oldDrawFb != oldReadFb) > - check_end_texture_render(ctx, oldDrawFb); > + _mesa_check_end_texture_render(ctx, oldDrawFb); > > /* check if newly bound framebuffer has any texture attachments */ > - check_begin_texture_render(ctx, newDrawFb); > + _mesa_check_begin_texture_render(ctx, newDrawFb); > > _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb); > } > diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h > index 7eb2005..ca6251c 100644 > --- a/src/mesa/main/fbobject.h > +++ b/src/mesa/main/fbobject.h > @@ -101,6 +101,12 @@ _mesa_is_legal_color_format(const struct gl_context > *ctx, GLenum baseFormat); > extern GLenum > _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat); > > +extern void > +_mesa_check_begin_texture_render(struct gl_context *ctx, struct > gl_framebuffer *fb); > + > +extern void > +_mesa_check_end_texture_render(struct gl_context *ctx, struct > gl_framebuffer *fb); > + > extern GLboolean GLAPIENTRY > _mesa_IsRenderbufferEXT(GLuint renderbuffer); > > diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak > index 4b2ec08..9af4079 100644 > --- a/src/mesa/sources.mak > +++ b/src/mesa/sources.mak > @@ -229,6 +229,7 @@ STATETRACKER_SOURCES = \ > state_tracker/st_debug.c \ > state_tracker/st_draw.c \ > state_tracker/st_draw_feedback.c \ > + state_tracker/st_draw_select_emul.c \ > state_tracker/st_extensions.c \ > state_tracker/st_format.c \ > state_tracker/st_gen_mipmap.c \ > diff --git a/src/mesa/state_tracker/st_cb_feedback.c > b/src/mesa/state_tracker/st_cb_feedback.c > index 9b85a39..c96c97c 100644 > --- a/src/mesa/state_tracker/st_cb_feedback.c > +++ b/src/mesa/state_tracker/st_cb_feedback.c > @@ -276,17 +276,28 @@ st_RenderMode(struct gl_context *ctx, GLenum newMode > ) > { > struct st_context *st = st_context(ctx); > struct draw_context *draw = st->draw; > + bool hw_acc_path = _mesa_getenv("MESA_HW_SELECT") && > !st->select_emul.hw_unsupported; > > if (newMode == GL_RENDER) { > /* restore normal VBO draw function */ > vbo_set_draw_func(ctx, st_draw_vbo); > } > else if (newMode == GL_SELECT) { > - if (!st->selection_stage) > - st->selection_stage = draw_glselect_stage(ctx, draw); > - draw_set_rasterize_stage(draw, st->selection_stage); > - /* Plug in new vbo draw function */ > - vbo_set_draw_func(ctx, st_feedback_draw_vbo); > + if (hw_acc_path) { > + if (st_select_emul_begin(ctx)) { > + vbo_set_draw_func(ctx, st_select_draw_func); > + } > + else { > + hw_acc_path = false; > + } > + } > + if (!hw_acc_path) { > + if (!st->selection_stage) > + st->selection_stage = draw_glselect_stage(ctx, draw); > + draw_set_rasterize_stage(draw, st->selection_stage); > + /* Plug in new vbo draw function */ > + vbo_set_draw_func(ctx, st_feedback_draw_vbo); > + } > } > else { > if (!st->feedback_stage) > diff --git a/src/mesa/state_tracker/st_context.h > b/src/mesa/state_tracker/st_context.h > index 0a32202..8a8e11a 100644 > --- a/src/mesa/state_tracker/st_context.h > +++ b/src/mesa/state_tracker/st_context.h > @@ -207,6 +207,16 @@ struct st_context > > int32_t draw_stamp; > int32_t read_stamp; > + > + /* data related to hw accelerated GL_SELECT */ > + struct gl_selection_emul > + { > + GLboolean hw_unsupported; > + struct gl_framebuffer *fbo; > + GLuint rb_depth_name; > + GLuint rb_color_name; > + void *fs; > + } select_emul; > }; > > > diff --git a/src/mesa/state_tracker/st_draw.h > b/src/mesa/state_tracker/st_draw.h > index a7b50ce..d27e321 100644 > --- a/src/mesa/state_tracker/st_draw.h > +++ b/src/mesa/state_tracker/st_draw.h > @@ -87,5 +87,22 @@ pointer_to_offset(const void *ptr) > return (unsigned) (((unsigned long) ptr) & 0xffffffffUL); > } > > +/* Functions used by the hw accelerated GL_SELECT emulator > + */ > +extern bool > +st_select_emul_begin(struct gl_context *ctx); > + > +extern void > +st_select_emul_end(struct gl_context *ctx); > + > +extern void > +st_select_draw_func(struct gl_context *ctx, > + const struct gl_client_array **arrays, > + const struct _mesa_prim *prims, > + GLuint nr_prims, > + const struct _mesa_index_buffer *ib, > + GLboolean index_bounds_valid, > + GLuint min_index, > + GLuint max_index); > > #endif > diff --git a/src/mesa/state_tracker/st_draw_select_emul.c > b/src/mesa/state_tracker/st_draw_select_emul.c > new file mode 100644 > index 0000000..d6bb244 > --- /dev/null > +++ b/src/mesa/state_tracker/st_draw_select_emul.c > @@ -0,0 +1,490 @@ > > +/************************************************************************** > + * > + * Copyright 2011 Micael Dias <kam1kaz3 (at) gmail (dot) com>, > + * Pierre-Eric Pelloux-Prayer > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sub license, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. > + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF > CONTRACT, > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + > **************************************************************************/ > + > +/** > + * This file contains code that attempts to accelerate GL_SELECT > rendering. > + * It was created with the intent of solving the following bug: > + * https://bugs.freedesktop.org/show_bug.cgi?id=34495 > + * > + * This code is a rewritten version of the patch "GL_SELECT hw support v5" > + * posted by user Pierre-Eric Pelloux-Prayer in the previously mentioned > bug. > + * > + * In order to test this code, the env. variable MESA_HW_SELECT should be > + * exported. > + * > + * How this algorithm works: > + * - When in GL_SELECT mode, draw calls are redirected to > st_select_draw_func() > + * which configures states in a way that makes the rendered primitives > draw > + * to a custom FBO that stores depth values (both min and max values) and > + * emits these values through _mesa_update_hitflag(). > + */ > + > +#include "main/imports.h" > +#include "main/image.h" > +#include "main/macros.h" > +#include "main/mfeatures.h" > +#include "main/hash.h" > + > +#include "main/context.h" > +#include "main/enable.h" > +#include "main/fbobject.h" > +#include "main/depth.h" > +#include "main/state.h" > +#include "main/scissor.h" > +#include "main/viewport.h" > +#include "main/framebuffer.h" > +#include "main/feedback.h" > + > +#include "vbo/vbo.h" > + > +#include "st_context.h" > +#include "st_atom.h" > +#include "st_cb_bufferobjects.h" > +#include "st_draw.h" > +#include "st_program.h" > +#include "st_texture.h" > +#include "st_cb_readpixels.h" > + > +#include "pipe/p_context.h" > +#include "pipe/p_defines.h" > +#include "pipe/p_state.h" > +#include "pipe/p_format.h" > +#include "pipe/p_shader_tokens.h" > +#include "util/u_inlines.h" > +#include "util/u_simple_shaders.h" > +#include "cso_cache/cso_context.h" > +#include "tgsi/tgsi_ureg.h" > + > +#include "draw/draw_private.h" > +#include "draw/draw_context.h" > + > +/** > + * Custom fragment shader that does nothing but ouput a constant color > + */ > +static void* > +st_select_emul_create_fs(struct gl_context *ctx) > +{ > + struct st_context *st = st_context(ctx); > + struct pipe_context *pipe = st->pipe; > + struct ureg_program *ureg; > + struct ureg_dst out; > + struct ureg_src imm; > + > + ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); > + if (ureg == NULL) > + return NULL; > + > + out = ureg_DECL_output( ureg, > + TGSI_SEMANTIC_COLOR, > + 0 ); > + > + imm = ureg_imm4f( ureg, 0.0f, 0.0f, 0.0f, 1.0f ); > + > + ureg_MOV( ureg, out, imm ); > + ureg_END( ureg ); > + > + return ureg_create_shader_and_destroy( ureg, pipe ); > +} > + > +/** > + * Clears the depth values of our FBO by setting the > + * 1st pixel to 1.0f and the 2nd to 0.0f > + */ > +static void > +st_select_emul_clear_fbo(struct gl_context *ctx) > +{ > + struct st_context *st = st_context(ctx); > + struct gl_scissor_attrib saved_scissor; > + struct gl_framebuffer *saved_fbo = NULL; > + GLfloat clearDepth; > + > + /* save states */ > + saved_scissor = ctx->Scissor; > + if (ctx->DrawBuffer) { > + _mesa_reference_framebuffer(&saved_fbo, ctx->DrawBuffer); > + } > + clearDepth = ctx->Depth.Clear; > + > + /* hack needed because Clear does nothing if render mode != GL_RENDER > */ > + ctx->RenderMode = GL_RENDER; > + > + /* disable old draw fbo */ > + if (saved_fbo) { > + /* XXX: needs flushing? */ > + _mesa_check_end_texture_render(ctx, saved_fbo); > + } > + > + /* use our fbo */ > + _mesa_check_begin_texture_render(ctx, st->select_emul.fbo); > + _mesa_reference_framebuffer(&ctx->DrawBuffer, st->select_emul.fbo); > + > + /* update fbo */ > + _mesa_update_framebuffer(ctx); > + > + /* make sure context is up to date */ > + _mesa_update_state(ctx); > + > + /* enable scissor */ > + ctx->Scissor.Enabled = GL_TRUE; > + > + /* clear min-Z */ > + ctx->Scissor.X = 0; > + ctx->Scissor.Y = 0; > + ctx->Scissor.Width = 1; > + ctx->Scissor.Height = 1; > + ctx->Depth.Clear = 1.0f; > + if (ctx->Driver.ClearDepth) > + (*ctx->Driver.ClearDepth)(ctx, ctx->Depth.Clear); > + ctx->NewState |= _NEW_SCISSOR | _NEW_DEPTH | _NEW_BUFFERS; > + _mesa_update_state(ctx); > + ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); > + > + /* clear max-Z */ > + ctx->Scissor.X = 1; > + ctx->Scissor.Y = 0; > + ctx->Scissor.Width = 1; > + ctx->Scissor.Height = 1; > + ctx->Depth.Clear = 0.0f; > + if (ctx->Driver.ClearDepth) > + (*ctx->Driver.ClearDepth)(ctx, ctx->Depth.Clear); > + ctx->NewState |= _NEW_SCISSOR | _NEW_DEPTH; > + _mesa_update_state(ctx); > + ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); > + > + /* restore states */ > + _mesa_check_end_texture_render(ctx, st->select_emul.fbo); > + if (saved_fbo) { > + _mesa_check_begin_texture_render(ctx, saved_fbo); > + _mesa_reference_framebuffer(&ctx->DrawBuffer, saved_fbo); > + _mesa_reference_framebuffer(&saved_fbo, NULL); > + } > + else > + _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL); > + > + ctx->RenderMode = GL_SELECT; > + ctx->Depth.Clear = clearDepth; > + if (ctx->Driver.ClearDepth) > + (*ctx->Driver.ClearDepth)(ctx, ctx->Depth.Clear); > + ctx->Scissor = saved_scissor; > + ctx->NewState |= _NEW_SCISSOR | _NEW_DEPTH | _NEW_BUFFERS; > + _mesa_update_state(ctx); > +} > + > +/** > + * Clean up data > + */ > +static void > +st_select_emul_destroy_fbo(struct gl_context *ctx) > +{ > + struct st_context *st = st_context(ctx); > + if (st->select_emul.rb_color_name) { > + _mesa_DeleteRenderbuffersEXT(1, &st->select_emul.rb_color_name); > + st->select_emul.rb_color_name = 0; > + } > + if (st->select_emul.rb_depth_name) { > + _mesa_DeleteRenderbuffersEXT(1, &st->select_emul.rb_depth_name); > + st->select_emul.rb_depth_name = 0; > + } > + if (st->select_emul.fbo) { > + _mesa_DeleteFramebuffersEXT(1, &st->select_emul.fbo->Name); > + _mesa_reference_framebuffer(&st->select_emul.fbo, NULL); > + } > + if (st->select_emul.fs) { > + cso_delete_fragment_shader(st->cso_context, st->select_emul.fs); > + st->select_emul.fs = NULL; > + } > +} > + > +/** > + * Create and setup FBO needed for our operations > + */ > +static bool > +st_select_emul_create_fbo(struct gl_context *ctx) > +{ > + GLuint fboName; > + struct st_context *st = st_context(ctx); > + > + /* make sure we don't leak memory */ > + st_select_emul_destroy_fbo(ctx); > + > + /* create buffer names */ > + _mesa_GenFramebuffersEXT(1, &fboName); > + _mesa_GenRenderbuffersEXT(1, &st->select_emul.rb_depth_name); > + _mesa_GenRenderbuffersEXT(1, &st->select_emul.rb_color_name); > + > + /* allocate buffers' memory */ > + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER, fboName); > + _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, > st->select_emul.rb_depth_name); > + _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 2, > 1); > + _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, > st->select_emul.rb_color_name); > + _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 2, 1); > + _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, 0); > + > + /* setup fbo */ > + _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, > + GL_RENDERBUFFER, > + st->select_emul.rb_depth_name); > + _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, > + GL_RENDERBUFFER, > + st->select_emul.rb_color_name); > + > + if (_mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER) != > GL_FRAMEBUFFER_COMPLETE) { > + st_select_emul_destroy_fbo(ctx); > + return false; > + } > + > + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER, 0); > + > + /* get fbo pointer */ > + st->select_emul.fbo = _mesa_lookup_framebuffer(ctx, fboName); > + > + /* create fragment shader */ > + st->select_emul.fs = st_select_emul_create_fs(ctx); > + > + /* check fbo pointer validity */ > + if (!st->select_emul.fbo) { > + st_select_emul_destroy_fbo(ctx); > + return false; > + } > + > + return true; > +} > + > +/** > + * Called when entering GL_SELECT mode. > + * This function initializes our private data and clears > + * depth so that the next draw call will have it ready. > + */ > +bool > +st_select_emul_begin(struct gl_context *ctx) > +{ > + struct st_context *st = st_context(ctx); > + > + /* perform an hw caps check once */ > + static bool hw_checked = false; > + if (!hw_checked) { > + hw_checked = true; > + /* XXX: is this a proper way to check for hw support? */ > + if (!ctx->Driver.ReadPixels || > + !ctx->Driver.DrawPixels || > + !ctx->Driver.NewFramebuffer || > + !ctx->Driver.NewRenderbuffer) { > + st->select_emul.hw_unsupported = true; > + return false; > + } > + } > + > + /* initialize fbo if not yet initialized */ > + if (!st->select_emul.fbo) { > + if (!st_select_emul_create_fbo(ctx)) { > + return false; > + } > + } > + > + /* clear FBO */ > + st_select_emul_clear_fbo(ctx); > + > + return true; > +} > + > +void > +st_select_emul_end(struct gl_context *ctx) > +{ > + st_select_emul_destroy_fbo(ctx); > +} > + > +/** > + * Reads into our FBO and emit z-buffer results > + * called by st_select_draw_func() > + */ > +static void > +st_select_emul_update_hits(struct gl_context *ctx) > +{ > + struct st_context *st = st_context(ctx); > + struct gl_framebuffer *saved_fbo = NULL; > + float zData[2]; > + > + /* set state */ > + if (ctx->ReadBuffer) { > + _mesa_reference_framebuffer(&saved_fbo, ctx->ReadBuffer); > + _mesa_check_end_texture_render(ctx, saved_fbo); > + } > + _mesa_check_begin_texture_render(ctx, st->select_emul.fbo); > + _mesa_reference_framebuffer(&ctx->ReadBuffer, st->select_emul.fbo); > + > + /* update fbo */ > + _mesa_update_framebuffer( ctx ); > + > + /* update state */ > + ctx->NewState |= _NEW_BUFFERS; > + _mesa_update_state( ctx ); > + > + /* read pixels */ > + ctx->Driver.ReadPixels( ctx, 0, 0, 2, 1, > + GL_DEPTH_COMPONENT, GL_FLOAT, > + &ctx->Pack, (void*)zData ); > + > + /* emit z-buffer results */ > + if (zData[0] != 1.0f) > + _mesa_update_hitflag( ctx, zData[0] ); > + if (zData[1] != 0.0f) > + _mesa_update_hitflag( ctx, zData[1] ); > + > + /* clear FBO */ > + st_select_emul_clear_fbo(ctx); > + > + /* restore state */ > + _mesa_check_end_texture_render(ctx, st->select_emul.fbo); > + if (saved_fbo) { > + _mesa_check_begin_texture_render(ctx, saved_fbo); > + _mesa_reference_framebuffer(&ctx->ReadBuffer, saved_fbo); > + _mesa_reference_framebuffer(&saved_fbo, NULL); > + } > + else > + _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL); > + > + /* update state */ > + ctx->NewState |= _NEW_BUFFERS; > + _mesa_update_state( ctx ); > +} > + > +/** > + * Plug in draw function to draw in GL_SELECT mode. > + * This function does the following steps: > + * 1) render into the 1st pixel of our FBO with depth state > + * configured so that we get the lowest Z values > + * 2) render into the 2nd pixel of our FBO with depth state > + * configured so that we get the highest Z values > + * 3) calls st_select_emul_update_hits() to emit results > + */ > +void > +st_select_draw_func(struct gl_context *ctx, > + const struct gl_client_array **arrays, > + const struct _mesa_prim *prims, > + GLuint nr_prims, > + const struct _mesa_index_buffer *ib, > + GLboolean index_bounds_valid, > + GLuint min_index, > + GLuint max_index) > +{ > + GLboolean saved_scissorEnabled; > + struct gl_framebuffer *saved_fbo = NULL; > + struct st_context *st = st_context(ctx); > + struct pipe_depth_stencil_alpha_state state_depth; > + struct pipe_viewport_state state_viewport; > + > + /* save states */ > + if (ctx->DrawBuffer) > + _mesa_reference_framebuffer(&saved_fbo, ctx->DrawBuffer); > + > + saved_scissorEnabled = ctx->Scissor.Enabled; > + cso_save_fragment_shader(st->cso_context); > + cso_save_depth_stencil_alpha(st->cso_context); > + cso_save_viewport(st->cso_context); > + > + /* prepare stencil state */ > + memset(&state_depth, 0, sizeof(state_depth)); > + state_depth.depth.enabled = 1; > + state_depth.depth.writemask = 1; > + > + /* prepare viewport state */ > + memset(&state_viewport, 0, sizeof(state_viewport)); > + state_viewport.scale[0] = 0.5f * 2.0f * 0.5; > + state_viewport.scale[1] = 0.5f * 1.0f; > + state_viewport.scale[2] = 1.0f; > + state_viewport.scale[3] = 1.0f; > + state_viewport.translate[1] = 0.5f * 1.0f; > + state_viewport.translate[2] = 0.0f; > + state_viewport.translate[3] = 0.0f; > + > + /* use our custom fragment shader */ > + cso_set_fragment_shader_handle(st->cso_context, st->select_emul.fs); > + > + /* disable scissor */ > + ctx->Scissor.Enabled = GL_FALSE; > + > + /* disable old draw fbo */ > + if (saved_fbo) > + _mesa_check_end_texture_render(ctx, saved_fbo); > + > + /* use our fbo */ > + _mesa_check_begin_texture_render(ctx, st->select_emul.fbo); > + _mesa_reference_framebuffer(&ctx->DrawBuffer, st->select_emul.fbo); > + > + /* update fbo */ > + _mesa_update_framebuffer( ctx ); > + > + /* update context */ > + _mesa_update_state(ctx); > + > + /* render min-z */ > + { > + /* specific states */ > + state_depth.depth.func = PIPE_FUNC_LESS; > + state_viewport.translate[0] = 0.5f * 1.0f + 0.0f; > + > + cso_set_depth_stencil_alpha(st->cso_context, &state_depth); > + cso_set_viewport(st->cso_context, &state_viewport); > + > + /* draw */ > + st_draw_vbo(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, > min_index, max_index); > + } > + > + /* render max-z */ > + { > + state_depth.depth.func = PIPE_FUNC_GREATER; > + state_viewport.translate[0] = 0.5f * 1.0f + 1.0f; > + > + cso_set_depth_stencil_alpha(st->cso_context, &state_depth); > + cso_set_viewport(st->cso_context, &state_viewport); > + > + /* draw */ > + st_draw_vbo(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, > min_index, max_index); > + } > + > + /* XXX: needs flushing? */ > + > + /* restore states */ > + cso_restore_fragment_shader(st->cso_context); > + cso_restore_depth_stencil_alpha(st->cso_context); > + cso_restore_viewport(st->cso_context); > + ctx->Scissor.Enabled = saved_scissorEnabled; > + _mesa_check_end_texture_render(ctx, st->select_emul.fbo); > + if (saved_fbo) { > + _mesa_check_begin_texture_render(ctx, saved_fbo); > + _mesa_reference_framebuffer(&ctx->DrawBuffer, saved_fbo); > + _mesa_reference_framebuffer(&saved_fbo, NULL); > + } > + else > + _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL); > + _mesa_update_state(ctx); > + > + /* update hits */ > + st_select_emul_update_hits(ctx); > +} > + > -- > 1.7.6 > > -- Micael Dias
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev