1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 * GL_SELECT and GL_FEEDBACK render modes.
30 * Basically, we use a private instance of the 'draw' module for doing
31 * selection/feedback. It would be nice to use the transform_feedback
32 * hardware feature, but it's defined as happening pre-clip and we want
33 * post-clipped primitives. Also, there's concerns about the efficiency
34 * of using the hardware for this anyway.
40 #include "main/imports.h"
41 #include "main/context.h"
42 #include "main/feedback.h"
43 #include "main/macros.h"
46 #include "vbo/vbo_context.h"
48 #include "st_context.h"
51 #include "st_cb_feedback.h"
52 #include "st_cb_bufferobjects.h"
54 #include "pipe/p_context.h"
55 #include "pipe/p_defines.h"
56 #include "pipe/p_winsys.h"
59 #include "pipe/draw/draw_context.h"
60 #include "pipe/draw/draw_private.h"
64 * This is actually used for both feedback and selection.
68 struct draw_stage stage
; /**< Base class */
69 GLcontext
*ctx
; /**< Rendering context */
70 GLboolean reset_stipple_counter
;
74 /**********************************************************************
75 * GL Feedback functions
76 **********************************************************************/
78 static INLINE
struct feedback_stage
*
79 feedback_stage( struct draw_stage
*stage
)
81 return (struct feedback_stage
*)stage
;
86 feedback_vertex(GLcontext
*ctx
, const struct draw_context
*draw
,
87 const struct vertex_header
*v
)
89 const struct st_context
*st
= ctx
->st
;
91 const GLfloat
*color
, *texcoord
;
95 win
[0] = v
->data
[0][0];
96 win
[1] = v
->data
[0][1];
97 win
[2] = v
->data
[0][2];
98 win
[3] = 1.0F
/ v
->data
[0][3];
101 * When we compute vertex layout, save info about position of the
102 * color and texcoord attribs to use here.
105 slot
= st
->vertex_result_to_slot
[VERT_RESULT_COL0
];
107 color
= v
->data
[slot
];
109 color
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
111 slot
= st
->vertex_result_to_slot
[VERT_RESULT_TEX0
];
113 texcoord
= v
->data
[slot
];
115 texcoord
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
117 _mesa_feedback_vertex(ctx
, win
, color
, ci
, texcoord
);
122 feedback_tri( struct draw_stage
*stage
, struct prim_header
*prim
)
124 struct feedback_stage
*fs
= feedback_stage(stage
);
125 struct draw_context
*draw
= stage
->draw
;
126 FEEDBACK_TOKEN(fs
->ctx
, (GLfloat
) GL_POLYGON_TOKEN
);
127 FEEDBACK_TOKEN(fs
->ctx
, (GLfloat
) 3); /* three vertices */
128 feedback_vertex(fs
->ctx
, draw
, prim
->v
[0]);
129 feedback_vertex(fs
->ctx
, draw
, prim
->v
[1]);
130 feedback_vertex(fs
->ctx
, draw
, prim
->v
[2]);
135 feedback_line( struct draw_stage
*stage
, struct prim_header
*prim
)
137 struct feedback_stage
*fs
= feedback_stage(stage
);
138 struct draw_context
*draw
= stage
->draw
;
139 if (fs
->reset_stipple_counter
) {
140 FEEDBACK_TOKEN(fs
->ctx
, (GLfloat
) GL_LINE_RESET_TOKEN
);
141 fs
->reset_stipple_counter
= GL_FALSE
;
144 FEEDBACK_TOKEN(fs
->ctx
, (GLfloat
) GL_LINE_TOKEN
);
146 feedback_vertex(fs
->ctx
, draw
, prim
->v
[0]);
147 feedback_vertex(fs
->ctx
, draw
, prim
->v
[1]);
152 feedback_point( struct draw_stage
*stage
, struct prim_header
*prim
)
154 struct feedback_stage
*fs
= feedback_stage(stage
);
155 struct draw_context
*draw
= stage
->draw
;
156 FEEDBACK_TOKEN(fs
->ctx
, (GLfloat
) GL_POINT_TOKEN
);
157 feedback_vertex(fs
->ctx
, draw
, prim
->v
[0]);
162 feedback_end( struct draw_stage
*stage
)
169 feedback_begin( struct draw_stage
*stage
)
176 feedback_reset_stipple_counter( struct draw_stage
*stage
)
178 struct feedback_stage
*fs
= feedback_stage(stage
);
179 fs
->reset_stipple_counter
= GL_TRUE
;
184 * Create GL feedback drawing stage.
186 static struct draw_stage
*
187 draw_glfeedback_stage(GLcontext
*ctx
, struct draw_context
*draw
)
189 struct feedback_stage
*fs
= CALLOC_STRUCT(feedback_stage
);
191 fs
->stage
.draw
= draw
;
192 fs
->stage
.next
= NULL
;
193 fs
->stage
.begin
= feedback_begin
;
194 fs
->stage
.point
= feedback_point
;
195 fs
->stage
.line
= feedback_line
;
196 fs
->stage
.tri
= feedback_tri
;
197 fs
->stage
.end
= feedback_end
;
198 fs
->stage
.reset_stipple_counter
= feedback_reset_stipple_counter
;
206 /**********************************************************************
207 * GL Selection functions
208 **********************************************************************/
211 select_tri( struct draw_stage
*stage
, struct prim_header
*prim
)
213 struct feedback_stage
*fs
= feedback_stage(stage
);
214 _mesa_update_hitflag( fs
->ctx
, prim
->v
[0]->data
[0][2] );
215 _mesa_update_hitflag( fs
->ctx
, prim
->v
[1]->data
[0][2] );
216 _mesa_update_hitflag( fs
->ctx
, prim
->v
[2]->data
[0][2] );
220 select_line( struct draw_stage
*stage
, struct prim_header
*prim
)
222 struct feedback_stage
*fs
= feedback_stage(stage
);
223 _mesa_update_hitflag( fs
->ctx
, prim
->v
[0]->data
[0][2] );
224 _mesa_update_hitflag( fs
->ctx
, prim
->v
[1]->data
[0][2] );
229 select_point( struct draw_stage
*stage
, struct prim_header
*prim
)
231 struct feedback_stage
*fs
= feedback_stage(stage
);
232 _mesa_update_hitflag( fs
->ctx
, prim
->v
[0]->data
[0][2] );
237 select_begin( struct draw_stage
*stage
)
244 select_end( struct draw_stage
*stage
)
251 select_reset_stipple_counter( struct draw_stage
*stage
)
258 * Create GL selection mode drawing stage.
260 static struct draw_stage
*
261 draw_glselect_stage(GLcontext
*ctx
, struct draw_context
*draw
)
263 struct feedback_stage
*fs
= CALLOC_STRUCT(feedback_stage
);
265 fs
->stage
.draw
= draw
;
266 fs
->stage
.next
= NULL
;
267 fs
->stage
.begin
= select_begin
;
268 fs
->stage
.point
= select_point
;
269 fs
->stage
.line
= select_line
;
270 fs
->stage
.tri
= select_tri
;
271 fs
->stage
.end
= select_end
;
272 fs
->stage
.reset_stipple_counter
= select_reset_stipple_counter
;
280 st_RenderMode(GLcontext
*ctx
, GLenum newMode
)
282 struct st_context
*st
= ctx
->st
;
283 struct vbo_context
*vbo
= (struct vbo_context
*) ctx
->swtnl_im
;
284 struct draw_context
*draw
= st
->draw
;
286 if (newMode
== GL_RENDER
) {
287 /* restore normal VBO draw function */
288 vbo
->draw_prims
= st_draw_vbo
;
290 else if (newMode
== GL_SELECT
) {
291 if (!st
->selection_stage
)
292 st
->selection_stage
= draw_glselect_stage(ctx
, draw
);
293 draw_set_rasterize_stage(draw
, st
->selection_stage
);
294 /* Plug in new vbo draw function */
295 vbo
->draw_prims
= st_feedback_draw_vbo
;
296 /* setup post-transform vertex attribs */
298 /* just emit pos as GLfloat[4] */
299 static const uint attrs
[1] = { FORMAT_4F
};
300 const interp_mode
*interp
= NULL
;
301 draw_set_vertex_attributes(draw
, attrs
, interp
, 1);
305 if (!st
->feedback_stage
)
306 st
->feedback_stage
= draw_glfeedback_stage(ctx
, draw
);
307 draw_set_rasterize_stage(draw
, st
->feedback_stage
);
308 /* Plug in new vbo draw function */
309 vbo
->draw_prims
= st_feedback_draw_vbo
;
315 void st_init_feedback_functions(struct dd_function_table
*functions
)
317 functions
->RenderMode
= st_RenderMode
;