1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
15*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
16*61046927SAndroid Build Coastguard Worker *
17*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker */
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker /**
27*61046927SAndroid Build Coastguard Worker * \file feedback.c
28*61046927SAndroid Build Coastguard Worker * Selection and feedback modes functions.
29*61046927SAndroid Build Coastguard Worker */
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
33*61046927SAndroid Build Coastguard Worker #include "c99_alloca.h"
34*61046927SAndroid Build Coastguard Worker #include "context.h"
35*61046927SAndroid Build Coastguard Worker #include "enums.h"
36*61046927SAndroid Build Coastguard Worker #include "feedback.h"
37*61046927SAndroid Build Coastguard Worker #include "macros.h"
38*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
39*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
40*61046927SAndroid Build Coastguard Worker #include "bufferobj.h"
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_feedback.h"
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker #define FB_3D 0x01
45*61046927SAndroid Build Coastguard Worker #define FB_4D 0x02
46*61046927SAndroid Build Coastguard Worker #define FB_COLOR 0x04
47*61046927SAndroid Build Coastguard Worker #define FB_TEXTURE 0X08
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FeedbackBuffer(GLsizei size,GLenum type,GLfloat * buffer)52*61046927SAndroid Build Coastguard Worker _mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
53*61046927SAndroid Build Coastguard Worker {
54*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode==GL_FEEDBACK) {
57*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" );
58*61046927SAndroid Build Coastguard Worker return;
59*61046927SAndroid Build Coastguard Worker }
60*61046927SAndroid Build Coastguard Worker if (size<0) {
61*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" );
62*61046927SAndroid Build Coastguard Worker return;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker if (!buffer && size > 0) {
65*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" );
66*61046927SAndroid Build Coastguard Worker ctx->Feedback.BufferSize = 0;
67*61046927SAndroid Build Coastguard Worker return;
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker switch (type) {
71*61046927SAndroid Build Coastguard Worker case GL_2D:
72*61046927SAndroid Build Coastguard Worker ctx->Feedback._Mask = 0;
73*61046927SAndroid Build Coastguard Worker break;
74*61046927SAndroid Build Coastguard Worker case GL_3D:
75*61046927SAndroid Build Coastguard Worker ctx->Feedback._Mask = FB_3D;
76*61046927SAndroid Build Coastguard Worker break;
77*61046927SAndroid Build Coastguard Worker case GL_3D_COLOR:
78*61046927SAndroid Build Coastguard Worker ctx->Feedback._Mask = (FB_3D | FB_COLOR);
79*61046927SAndroid Build Coastguard Worker break;
80*61046927SAndroid Build Coastguard Worker case GL_3D_COLOR_TEXTURE:
81*61046927SAndroid Build Coastguard Worker ctx->Feedback._Mask = (FB_3D | FB_COLOR | FB_TEXTURE);
82*61046927SAndroid Build Coastguard Worker break;
83*61046927SAndroid Build Coastguard Worker case GL_4D_COLOR_TEXTURE:
84*61046927SAndroid Build Coastguard Worker ctx->Feedback._Mask = (FB_3D | FB_4D | FB_COLOR | FB_TEXTURE);
85*61046927SAndroid Build Coastguard Worker break;
86*61046927SAndroid Build Coastguard Worker default:
87*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" );
88*61046927SAndroid Build Coastguard Worker return;
89*61046927SAndroid Build Coastguard Worker }
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_RENDERMODE, 0); /* Always flush */
92*61046927SAndroid Build Coastguard Worker ctx->Feedback.Type = type;
93*61046927SAndroid Build Coastguard Worker ctx->Feedback.BufferSize = size;
94*61046927SAndroid Build Coastguard Worker ctx->Feedback.Buffer = buffer;
95*61046927SAndroid Build Coastguard Worker ctx->Feedback.Count = 0; /* Because of this. */
96*61046927SAndroid Build Coastguard Worker }
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_PassThrough(GLfloat token)100*61046927SAndroid Build Coastguard Worker _mesa_PassThrough( GLfloat token )
101*61046927SAndroid Build Coastguard Worker {
102*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode==GL_FEEDBACK) {
105*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
106*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN );
107*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, token );
108*61046927SAndroid Build Coastguard Worker }
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker /**
113*61046927SAndroid Build Coastguard Worker * Put a vertex into the feedback buffer.
114*61046927SAndroid Build Coastguard Worker */
115*61046927SAndroid Build Coastguard Worker void
_mesa_feedback_vertex(struct gl_context * ctx,const GLfloat win[4],const GLfloat color[4],const GLfloat texcoord[4])116*61046927SAndroid Build Coastguard Worker _mesa_feedback_vertex(struct gl_context *ctx,
117*61046927SAndroid Build Coastguard Worker const GLfloat win[4],
118*61046927SAndroid Build Coastguard Worker const GLfloat color[4],
119*61046927SAndroid Build Coastguard Worker const GLfloat texcoord[4])
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, win[0] );
122*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, win[1] );
123*61046927SAndroid Build Coastguard Worker if (ctx->Feedback._Mask & FB_3D) {
124*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, win[2] );
125*61046927SAndroid Build Coastguard Worker }
126*61046927SAndroid Build Coastguard Worker if (ctx->Feedback._Mask & FB_4D) {
127*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, win[3] );
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker if (ctx->Feedback._Mask & FB_COLOR) {
130*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, color[0] );
131*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, color[1] );
132*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, color[2] );
133*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, color[3] );
134*61046927SAndroid Build Coastguard Worker }
135*61046927SAndroid Build Coastguard Worker if (ctx->Feedback._Mask & FB_TEXTURE) {
136*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, texcoord[0] );
137*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, texcoord[1] );
138*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, texcoord[2] );
139*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, texcoord[3] );
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker }
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker /**********************************************************************/
145*61046927SAndroid Build Coastguard Worker /** \name Selection */
146*61046927SAndroid Build Coastguard Worker /*@{*/
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker /**
149*61046927SAndroid Build Coastguard Worker * Establish a buffer for selection mode values.
150*61046927SAndroid Build Coastguard Worker *
151*61046927SAndroid Build Coastguard Worker * \param size buffer size.
152*61046927SAndroid Build Coastguard Worker * \param buffer buffer.
153*61046927SAndroid Build Coastguard Worker *
154*61046927SAndroid Build Coastguard Worker * \sa glSelectBuffer().
155*61046927SAndroid Build Coastguard Worker *
156*61046927SAndroid Build Coastguard Worker * \note this function can't be put in a display list.
157*61046927SAndroid Build Coastguard Worker *
158*61046927SAndroid Build Coastguard Worker * Verifies we're not in selection mode, flushes the vertices and initialize
159*61046927SAndroid Build Coastguard Worker * the fields in __struct gl_contextRec::Select with the given buffer.
160*61046927SAndroid Build Coastguard Worker */
161*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_SelectBuffer(GLsizei size,GLuint * buffer)162*61046927SAndroid Build Coastguard Worker _mesa_SelectBuffer( GLsizei size, GLuint *buffer )
163*61046927SAndroid Build Coastguard Worker {
164*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker if (size < 0) {
167*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glSelectBuffer(size)");
168*61046927SAndroid Build Coastguard Worker return;
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode==GL_SELECT) {
172*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" );
173*61046927SAndroid Build Coastguard Worker return; /* KW: added return */
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_RENDERMODE, 0);
177*61046927SAndroid Build Coastguard Worker ctx->Select.Buffer = buffer;
178*61046927SAndroid Build Coastguard Worker ctx->Select.BufferSize = size;
179*61046927SAndroid Build Coastguard Worker ctx->Select.BufferCount = 0;
180*61046927SAndroid Build Coastguard Worker ctx->Select.HitFlag = GL_FALSE;
181*61046927SAndroid Build Coastguard Worker ctx->Select.HitMinZ = 1.0;
182*61046927SAndroid Build Coastguard Worker ctx->Select.HitMaxZ = 0.0;
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker /**
187*61046927SAndroid Build Coastguard Worker * Write a value of a record into the selection buffer.
188*61046927SAndroid Build Coastguard Worker *
189*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
190*61046927SAndroid Build Coastguard Worker * \param value value.
191*61046927SAndroid Build Coastguard Worker *
192*61046927SAndroid Build Coastguard Worker * Verifies there is free space in the buffer to write the value and
193*61046927SAndroid Build Coastguard Worker * increments the pointer.
194*61046927SAndroid Build Coastguard Worker */
195*61046927SAndroid Build Coastguard Worker static inline void
write_record(struct gl_context * ctx,GLuint value)196*61046927SAndroid Build Coastguard Worker write_record(struct gl_context *ctx, GLuint value)
197*61046927SAndroid Build Coastguard Worker {
198*61046927SAndroid Build Coastguard Worker if (ctx->Select.BufferCount < ctx->Select.BufferSize) {
199*61046927SAndroid Build Coastguard Worker ctx->Select.Buffer[ctx->Select.BufferCount] = value;
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker ctx->Select.BufferCount++;
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker /**
206*61046927SAndroid Build Coastguard Worker * Update the hit flag and the maximum and minimum depth values.
207*61046927SAndroid Build Coastguard Worker *
208*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
209*61046927SAndroid Build Coastguard Worker * \param z depth.
210*61046927SAndroid Build Coastguard Worker *
211*61046927SAndroid Build Coastguard Worker * Sets gl_selection::HitFlag and updates gl_selection::HitMinZ and
212*61046927SAndroid Build Coastguard Worker * gl_selection::HitMaxZ.
213*61046927SAndroid Build Coastguard Worker */
214*61046927SAndroid Build Coastguard Worker void
_mesa_update_hitflag(struct gl_context * ctx,GLfloat z)215*61046927SAndroid Build Coastguard Worker _mesa_update_hitflag(struct gl_context *ctx, GLfloat z)
216*61046927SAndroid Build Coastguard Worker {
217*61046927SAndroid Build Coastguard Worker ctx->Select.HitFlag = GL_TRUE;
218*61046927SAndroid Build Coastguard Worker if (z < ctx->Select.HitMinZ) {
219*61046927SAndroid Build Coastguard Worker ctx->Select.HitMinZ = z;
220*61046927SAndroid Build Coastguard Worker }
221*61046927SAndroid Build Coastguard Worker if (z > ctx->Select.HitMaxZ) {
222*61046927SAndroid Build Coastguard Worker ctx->Select.HitMaxZ = z;
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker
226*61046927SAndroid Build Coastguard Worker static void
alloc_select_resource(struct gl_context * ctx)227*61046927SAndroid Build Coastguard Worker alloc_select_resource(struct gl_context *ctx)
228*61046927SAndroid Build Coastguard Worker {
229*61046927SAndroid Build Coastguard Worker struct gl_selection *s = &ctx->Select;
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker if (!ctx->Const.HardwareAcceleratedSelect)
232*61046927SAndroid Build Coastguard Worker return;
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker if (!ctx->Dispatch.HWSelectModeBeginEnd) {
235*61046927SAndroid Build Coastguard Worker ctx->Dispatch.HWSelectModeBeginEnd = _mesa_alloc_dispatch_table(false);
236*61046927SAndroid Build Coastguard Worker if (!ctx->Dispatch.HWSelectModeBeginEnd) {
237*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot allocate HWSelectModeBeginEnd");
238*61046927SAndroid Build Coastguard Worker return;
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker vbo_init_dispatch_hw_select_begin_end(ctx);
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker if (!s->SaveBuffer) {
244*61046927SAndroid Build Coastguard Worker s->SaveBuffer = malloc(NAME_STACK_BUFFER_SIZE);
245*61046927SAndroid Build Coastguard Worker if (!s->SaveBuffer) {
246*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot allocate name stack save buffer");
247*61046927SAndroid Build Coastguard Worker return;
248*61046927SAndroid Build Coastguard Worker }
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker if (!s->Result) {
252*61046927SAndroid Build Coastguard Worker s->Result = _mesa_bufferobj_alloc(ctx, -1);
253*61046927SAndroid Build Coastguard Worker if (!s->Result) {
254*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot allocate select result buffer");
255*61046927SAndroid Build Coastguard Worker return;
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker GLuint init_result[MAX_NAME_STACK_RESULT_NUM * 3];
259*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MAX_NAME_STACK_RESULT_NUM; i++) {
260*61046927SAndroid Build Coastguard Worker init_result[i * 3] = 0; /* hit */
261*61046927SAndroid Build Coastguard Worker init_result[i * 3 + 1] = 0xffffffff; /* minz */
262*61046927SAndroid Build Coastguard Worker init_result[i * 3 + 2] = 0; /* maxz */
263*61046927SAndroid Build Coastguard Worker }
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker bool success = _mesa_bufferobj_data(ctx,
266*61046927SAndroid Build Coastguard Worker GL_SHADER_STORAGE_BUFFER,
267*61046927SAndroid Build Coastguard Worker sizeof(init_result),
268*61046927SAndroid Build Coastguard Worker init_result,
269*61046927SAndroid Build Coastguard Worker GL_STATIC_DRAW, 0,
270*61046927SAndroid Build Coastguard Worker s->Result);
271*61046927SAndroid Build Coastguard Worker if (!success) {
272*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &s->Result, NULL);
273*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot init result buffer");
274*61046927SAndroid Build Coastguard Worker return;
275*61046927SAndroid Build Coastguard Worker }
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker }
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker static bool
save_used_name_stack(struct gl_context * ctx)280*61046927SAndroid Build Coastguard Worker save_used_name_stack(struct gl_context *ctx)
281*61046927SAndroid Build Coastguard Worker {
282*61046927SAndroid Build Coastguard Worker struct gl_selection *s = &ctx->Select;
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker if (!ctx->Const.HardwareAcceleratedSelect)
285*61046927SAndroid Build Coastguard Worker return false;
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker /* We have two kinds of name stack user:
288*61046927SAndroid Build Coastguard Worker * 1. glRasterPos (CPU based) will set HitFlag
289*61046927SAndroid Build Coastguard Worker * 2. draw call for GPU will set ResultUsed
290*61046927SAndroid Build Coastguard Worker */
291*61046927SAndroid Build Coastguard Worker if (!s->ResultUsed && !s->HitFlag)
292*61046927SAndroid Build Coastguard Worker return false;
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker void *save = (char *)s->SaveBuffer + s->SaveBufferTail;
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker /* save meta data */
297*61046927SAndroid Build Coastguard Worker uint8_t *metadata = save;
298*61046927SAndroid Build Coastguard Worker metadata[0] = s->HitFlag;
299*61046927SAndroid Build Coastguard Worker metadata[1] = s->ResultUsed;
300*61046927SAndroid Build Coastguard Worker metadata[2] = s->NameStackDepth;
301*61046927SAndroid Build Coastguard Worker metadata[3] = 0;
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker /* save hit data */
304*61046927SAndroid Build Coastguard Worker int index = 1;
305*61046927SAndroid Build Coastguard Worker if (s->HitFlag) {
306*61046927SAndroid Build Coastguard Worker float *hit = save;
307*61046927SAndroid Build Coastguard Worker hit[index++] = s->HitMinZ;
308*61046927SAndroid Build Coastguard Worker hit[index++] = s->HitMaxZ;
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker /* save name stack */
312*61046927SAndroid Build Coastguard Worker memcpy((uint32_t *)save + index, s->NameStack, s->NameStackDepth * sizeof(GLuint));
313*61046927SAndroid Build Coastguard Worker index += s->NameStackDepth;
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker s->SaveBufferTail += index * sizeof(GLuint);
316*61046927SAndroid Build Coastguard Worker s->SavedStackNum++;
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker /* if current slot has been used, store result to next slot in result buffer */
319*61046927SAndroid Build Coastguard Worker if (s->ResultUsed)
320*61046927SAndroid Build Coastguard Worker s->ResultOffset += 3 * sizeof(GLuint);
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker /* reset fields */
323*61046927SAndroid Build Coastguard Worker s->HitFlag = GL_FALSE;
324*61046927SAndroid Build Coastguard Worker s->HitMinZ = 1.0;
325*61046927SAndroid Build Coastguard Worker s->HitMaxZ = 0;
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker s->ResultUsed = GL_FALSE;
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker /* return true if we have no enough space for the next name stack data */
330*61046927SAndroid Build Coastguard Worker return s->ResultOffset >= MAX_NAME_STACK_RESULT_NUM * 3 * sizeof(GLuint) ||
331*61046927SAndroid Build Coastguard Worker s->SaveBufferTail >= NAME_STACK_BUFFER_SIZE - (MAX_NAME_STACK_DEPTH + 3) * sizeof(GLuint);
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker static void
update_hit_record(struct gl_context * ctx)335*61046927SAndroid Build Coastguard Worker update_hit_record(struct gl_context *ctx)
336*61046927SAndroid Build Coastguard Worker {
337*61046927SAndroid Build Coastguard Worker struct gl_selection *s = &ctx->Select;
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker if (ctx->Const.HardwareAcceleratedSelect) {
340*61046927SAndroid Build Coastguard Worker if (!s->SavedStackNum)
341*61046927SAndroid Build Coastguard Worker return;
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker unsigned size = s->ResultOffset;
344*61046927SAndroid Build Coastguard Worker GLuint *result = size ? alloca(size) : NULL;
345*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_get_subdata(ctx, 0, size, result, s->Result);
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker unsigned index = 0;
348*61046927SAndroid Build Coastguard Worker unsigned *save = s->SaveBuffer;
349*61046927SAndroid Build Coastguard Worker for (int i = 0; i < s->SavedStackNum; i++) {
350*61046927SAndroid Build Coastguard Worker uint8_t *metadata = (uint8_t *)(save++);
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker unsigned zmin, zmax;
353*61046927SAndroid Build Coastguard Worker bool cpu_hit = !!metadata[0];
354*61046927SAndroid Build Coastguard Worker if (cpu_hit) {
355*61046927SAndroid Build Coastguard Worker /* map [0, 1] to [0, UINT_MAX]*/
356*61046927SAndroid Build Coastguard Worker zmin = (unsigned) ((float)(~0u) * *(float *)(save++));
357*61046927SAndroid Build Coastguard Worker zmax = (unsigned) ((float)(~0u) * *(float *)(save++));
358*61046927SAndroid Build Coastguard Worker } else {
359*61046927SAndroid Build Coastguard Worker zmin = ~0u;
360*61046927SAndroid Build Coastguard Worker zmax = 0;
361*61046927SAndroid Build Coastguard Worker }
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker bool gpu_hit = false;
364*61046927SAndroid Build Coastguard Worker if (metadata[1]) {
365*61046927SAndroid Build Coastguard Worker gpu_hit = !!result[index];
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker if (gpu_hit) {
368*61046927SAndroid Build Coastguard Worker zmin = MIN2(zmin, result[index + 1]);
369*61046927SAndroid Build Coastguard Worker zmax = MAX2(zmax, result[index + 2]);
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker /* reset data */
372*61046927SAndroid Build Coastguard Worker result[index] = 0; /* hit */
373*61046927SAndroid Build Coastguard Worker result[index + 1] = 0xffffffff; /* minz */
374*61046927SAndroid Build Coastguard Worker result[index + 2] = 0; /* maxz */
375*61046927SAndroid Build Coastguard Worker }
376*61046927SAndroid Build Coastguard Worker index += 3;
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker int depth = metadata[2];
380*61046927SAndroid Build Coastguard Worker if (cpu_hit || gpu_hit) {
381*61046927SAndroid Build Coastguard Worker /* hit */
382*61046927SAndroid Build Coastguard Worker write_record(ctx, depth);
383*61046927SAndroid Build Coastguard Worker write_record(ctx, zmin);
384*61046927SAndroid Build Coastguard Worker write_record(ctx, zmax);
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker for (int j = 0; j < depth; j++)
387*61046927SAndroid Build Coastguard Worker write_record(ctx, save[j]);
388*61046927SAndroid Build Coastguard Worker s->Hits++;
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker save += depth;
391*61046927SAndroid Build Coastguard Worker }
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker /* reset result buffer */
394*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_subdata(ctx, 0, size, result, s->Result);
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker s->SaveBufferTail = 0;
397*61046927SAndroid Build Coastguard Worker s->SavedStackNum = 0;
398*61046927SAndroid Build Coastguard Worker s->ResultOffset = 0;
399*61046927SAndroid Build Coastguard Worker } else {
400*61046927SAndroid Build Coastguard Worker if (!s->HitFlag)
401*61046927SAndroid Build Coastguard Worker return;
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */
404*61046927SAndroid Build Coastguard Worker /* 2^32-1 and round to nearest unsigned integer. */
405*61046927SAndroid Build Coastguard Worker GLuint zscale = (~0u);
406*61046927SAndroid Build Coastguard Worker GLuint zmin = (GLuint) ((GLfloat) zscale * s->HitMinZ);
407*61046927SAndroid Build Coastguard Worker GLuint zmax = (GLuint) ((GLfloat) zscale * s->HitMaxZ);
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker write_record(ctx, s->NameStackDepth);
410*61046927SAndroid Build Coastguard Worker write_record(ctx, zmin);
411*61046927SAndroid Build Coastguard Worker write_record(ctx, zmax);
412*61046927SAndroid Build Coastguard Worker for (int i = 0; i < s->NameStackDepth; i++)
413*61046927SAndroid Build Coastguard Worker write_record(ctx, s->NameStack[i]);
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker s->HitFlag = GL_FALSE;
416*61046927SAndroid Build Coastguard Worker s->HitMinZ = 1.0;
417*61046927SAndroid Build Coastguard Worker s->HitMaxZ = -1.0;
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker s->Hits++;
420*61046927SAndroid Build Coastguard Worker }
421*61046927SAndroid Build Coastguard Worker }
422*61046927SAndroid Build Coastguard Worker
423*61046927SAndroid Build Coastguard Worker static void
reset_name_stack_to_empty(struct gl_context * ctx)424*61046927SAndroid Build Coastguard Worker reset_name_stack_to_empty(struct gl_context *ctx)
425*61046927SAndroid Build Coastguard Worker {
426*61046927SAndroid Build Coastguard Worker struct gl_selection *s = &ctx->Select;
427*61046927SAndroid Build Coastguard Worker
428*61046927SAndroid Build Coastguard Worker s->NameStackDepth = 0;
429*61046927SAndroid Build Coastguard Worker s->HitFlag = GL_FALSE;
430*61046927SAndroid Build Coastguard Worker s->HitMinZ = 1.0;
431*61046927SAndroid Build Coastguard Worker s->HitMaxZ = 0.0;
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker if (ctx->Const.HardwareAcceleratedSelect) {
434*61046927SAndroid Build Coastguard Worker s->SaveBufferTail = 0;
435*61046927SAndroid Build Coastguard Worker s->SavedStackNum = 0;
436*61046927SAndroid Build Coastguard Worker s->ResultUsed = GL_FALSE;
437*61046927SAndroid Build Coastguard Worker s->ResultOffset = 0;
438*61046927SAndroid Build Coastguard Worker }
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker /**
442*61046927SAndroid Build Coastguard Worker * Initialize the name stack.
443*61046927SAndroid Build Coastguard Worker */
444*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InitNames(void)445*61046927SAndroid Build Coastguard Worker _mesa_InitNames( void )
446*61046927SAndroid Build Coastguard Worker {
447*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker /* Calls to glInitNames while the render mode is not GL_SELECT are ignored. */
450*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode != GL_SELECT)
451*61046927SAndroid Build Coastguard Worker return;
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker save_used_name_stack(ctx);
456*61046927SAndroid Build Coastguard Worker update_hit_record(ctx);
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker reset_name_stack_to_empty(ctx);
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker ctx->NewState |= _NEW_RENDERMODE;
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker /**
465*61046927SAndroid Build Coastguard Worker * Load the top-most name of the name stack.
466*61046927SAndroid Build Coastguard Worker *
467*61046927SAndroid Build Coastguard Worker * \param name name.
468*61046927SAndroid Build Coastguard Worker */
469*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_LoadName(GLuint name)470*61046927SAndroid Build Coastguard Worker _mesa_LoadName( GLuint name )
471*61046927SAndroid Build Coastguard Worker {
472*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode != GL_SELECT) {
475*61046927SAndroid Build Coastguard Worker return;
476*61046927SAndroid Build Coastguard Worker }
477*61046927SAndroid Build Coastguard Worker if (ctx->Select.NameStackDepth == 0) {
478*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_OPERATION, "glLoadName" );
479*61046927SAndroid Build Coastguard Worker return;
480*61046927SAndroid Build Coastguard Worker }
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker if (!ctx->Const.HardwareAcceleratedSelect || save_used_name_stack(ctx)) {
483*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
484*61046927SAndroid Build Coastguard Worker update_hit_record(ctx);
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name;
488*61046927SAndroid Build Coastguard Worker ctx->NewState |= _NEW_RENDERMODE;
489*61046927SAndroid Build Coastguard Worker }
490*61046927SAndroid Build Coastguard Worker
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker /**
493*61046927SAndroid Build Coastguard Worker * Push a name into the name stack.
494*61046927SAndroid Build Coastguard Worker *
495*61046927SAndroid Build Coastguard Worker * \param name name.
496*61046927SAndroid Build Coastguard Worker */
497*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_PushName(GLuint name)498*61046927SAndroid Build Coastguard Worker _mesa_PushName( GLuint name )
499*61046927SAndroid Build Coastguard Worker {
500*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode != GL_SELECT) {
503*61046927SAndroid Build Coastguard Worker return;
504*61046927SAndroid Build Coastguard Worker }
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) {
507*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" );
508*61046927SAndroid Build Coastguard Worker return;
509*61046927SAndroid Build Coastguard Worker }
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker if (!ctx->Const.HardwareAcceleratedSelect || save_used_name_stack(ctx)) {
512*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
513*61046927SAndroid Build Coastguard Worker update_hit_record(ctx);
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name;
517*61046927SAndroid Build Coastguard Worker ctx->NewState |= _NEW_RENDERMODE;
518*61046927SAndroid Build Coastguard Worker }
519*61046927SAndroid Build Coastguard Worker
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker /**
522*61046927SAndroid Build Coastguard Worker * Pop a name into the name stack.
523*61046927SAndroid Build Coastguard Worker */
524*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_PopName(void)525*61046927SAndroid Build Coastguard Worker _mesa_PopName( void )
526*61046927SAndroid Build Coastguard Worker {
527*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode != GL_SELECT) {
530*61046927SAndroid Build Coastguard Worker return;
531*61046927SAndroid Build Coastguard Worker }
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker if (ctx->Select.NameStackDepth == 0) {
534*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" );
535*61046927SAndroid Build Coastguard Worker return;
536*61046927SAndroid Build Coastguard Worker }
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker if (!ctx->Const.HardwareAcceleratedSelect || save_used_name_stack(ctx)) {
539*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
540*61046927SAndroid Build Coastguard Worker update_hit_record(ctx);
541*61046927SAndroid Build Coastguard Worker }
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker ctx->Select.NameStackDepth--;
544*61046927SAndroid Build Coastguard Worker ctx->NewState |= _NEW_RENDERMODE;
545*61046927SAndroid Build Coastguard Worker }
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker /*@}*/
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker /**********************************************************************/
551*61046927SAndroid Build Coastguard Worker /** \name Render Mode */
552*61046927SAndroid Build Coastguard Worker /*@{*/
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker /**
555*61046927SAndroid Build Coastguard Worker * Set rasterization mode.
556*61046927SAndroid Build Coastguard Worker *
557*61046927SAndroid Build Coastguard Worker * \param mode rasterization mode.
558*61046927SAndroid Build Coastguard Worker *
559*61046927SAndroid Build Coastguard Worker * \note this function can't be put in a display list.
560*61046927SAndroid Build Coastguard Worker *
561*61046927SAndroid Build Coastguard Worker * \sa glRenderMode().
562*61046927SAndroid Build Coastguard Worker *
563*61046927SAndroid Build Coastguard Worker * Flushes the vertices and do the necessary cleanup according to the previous
564*61046927SAndroid Build Coastguard Worker * rasterization mode, such as writing the hit record or resent the select
565*61046927SAndroid Build Coastguard Worker * buffer index when exiting the select mode. Updates
566*61046927SAndroid Build Coastguard Worker * __struct gl_contextRec::RenderMode and notifies the driver via the
567*61046927SAndroid Build Coastguard Worker * dd_function_table::RenderMode callback.
568*61046927SAndroid Build Coastguard Worker */
569*61046927SAndroid Build Coastguard Worker GLint GLAPIENTRY
_mesa_RenderMode(GLenum mode)570*61046927SAndroid Build Coastguard Worker _mesa_RenderMode( GLenum mode )
571*61046927SAndroid Build Coastguard Worker {
572*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
573*61046927SAndroid Build Coastguard Worker GLint result;
574*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
577*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glRenderMode %s\n", _mesa_enum_to_string(mode));
578*61046927SAndroid Build Coastguard Worker
579*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_RENDERMODE | _NEW_FF_VERT_PROGRAM |
580*61046927SAndroid Build Coastguard Worker _NEW_FF_FRAG_PROGRAM, 0);
581*61046927SAndroid Build Coastguard Worker
582*61046927SAndroid Build Coastguard Worker switch (ctx->RenderMode) {
583*61046927SAndroid Build Coastguard Worker case GL_RENDER:
584*61046927SAndroid Build Coastguard Worker result = 0;
585*61046927SAndroid Build Coastguard Worker break;
586*61046927SAndroid Build Coastguard Worker case GL_SELECT:
587*61046927SAndroid Build Coastguard Worker save_used_name_stack(ctx);
588*61046927SAndroid Build Coastguard Worker update_hit_record(ctx);
589*61046927SAndroid Build Coastguard Worker
590*61046927SAndroid Build Coastguard Worker if (ctx->Select.BufferCount > ctx->Select.BufferSize) {
591*61046927SAndroid Build Coastguard Worker /* overflow */
592*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
593*61046927SAndroid Build Coastguard Worker _mesa_warning(ctx, "Feedback buffer overflow");
594*61046927SAndroid Build Coastguard Worker #endif
595*61046927SAndroid Build Coastguard Worker result = -1;
596*61046927SAndroid Build Coastguard Worker }
597*61046927SAndroid Build Coastguard Worker else {
598*61046927SAndroid Build Coastguard Worker result = ctx->Select.Hits;
599*61046927SAndroid Build Coastguard Worker }
600*61046927SAndroid Build Coastguard Worker ctx->Select.BufferCount = 0;
601*61046927SAndroid Build Coastguard Worker ctx->Select.Hits = 0;
602*61046927SAndroid Build Coastguard Worker /* name stack should be in empty state after exiting GL_SELECT mode */
603*61046927SAndroid Build Coastguard Worker reset_name_stack_to_empty(ctx);
604*61046927SAndroid Build Coastguard Worker break;
605*61046927SAndroid Build Coastguard Worker case GL_FEEDBACK:
606*61046927SAndroid Build Coastguard Worker if (ctx->Feedback.Count > ctx->Feedback.BufferSize) {
607*61046927SAndroid Build Coastguard Worker /* overflow */
608*61046927SAndroid Build Coastguard Worker result = -1;
609*61046927SAndroid Build Coastguard Worker }
610*61046927SAndroid Build Coastguard Worker else {
611*61046927SAndroid Build Coastguard Worker result = ctx->Feedback.Count;
612*61046927SAndroid Build Coastguard Worker }
613*61046927SAndroid Build Coastguard Worker ctx->Feedback.Count = 0;
614*61046927SAndroid Build Coastguard Worker break;
615*61046927SAndroid Build Coastguard Worker default:
616*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
617*61046927SAndroid Build Coastguard Worker return 0;
618*61046927SAndroid Build Coastguard Worker }
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker switch (mode) {
621*61046927SAndroid Build Coastguard Worker case GL_RENDER:
622*61046927SAndroid Build Coastguard Worker break;
623*61046927SAndroid Build Coastguard Worker case GL_SELECT:
624*61046927SAndroid Build Coastguard Worker if (ctx->Select.BufferSize==0) {
625*61046927SAndroid Build Coastguard Worker /* haven't called glSelectBuffer yet */
626*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
627*61046927SAndroid Build Coastguard Worker }
628*61046927SAndroid Build Coastguard Worker alloc_select_resource(ctx);
629*61046927SAndroid Build Coastguard Worker break;
630*61046927SAndroid Build Coastguard Worker case GL_FEEDBACK:
631*61046927SAndroid Build Coastguard Worker if (ctx->Feedback.BufferSize==0) {
632*61046927SAndroid Build Coastguard Worker /* haven't called glFeedbackBuffer yet */
633*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
634*61046927SAndroid Build Coastguard Worker }
635*61046927SAndroid Build Coastguard Worker break;
636*61046927SAndroid Build Coastguard Worker default:
637*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
638*61046927SAndroid Build Coastguard Worker return 0;
639*61046927SAndroid Build Coastguard Worker }
640*61046927SAndroid Build Coastguard Worker
641*61046927SAndroid Build Coastguard Worker st_RenderMode( ctx, mode );
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker /* finally update render mode to new one */
644*61046927SAndroid Build Coastguard Worker ctx->RenderMode = mode;
645*61046927SAndroid Build Coastguard Worker
646*61046927SAndroid Build Coastguard Worker return result;
647*61046927SAndroid Build Coastguard Worker }
648*61046927SAndroid Build Coastguard Worker
649*61046927SAndroid Build Coastguard Worker /*@}*/
650*61046927SAndroid Build Coastguard Worker
651*61046927SAndroid Build Coastguard Worker
652*61046927SAndroid Build Coastguard Worker /**********************************************************************/
653*61046927SAndroid Build Coastguard Worker /** \name Initialization */
654*61046927SAndroid Build Coastguard Worker /*@{*/
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker /**
657*61046927SAndroid Build Coastguard Worker * Initialize context feedback data.
658*61046927SAndroid Build Coastguard Worker */
_mesa_init_feedback(struct gl_context * ctx)659*61046927SAndroid Build Coastguard Worker void _mesa_init_feedback( struct gl_context * ctx )
660*61046927SAndroid Build Coastguard Worker {
661*61046927SAndroid Build Coastguard Worker /* Feedback */
662*61046927SAndroid Build Coastguard Worker ctx->Feedback.Type = GL_2D; /* TODO: verify */
663*61046927SAndroid Build Coastguard Worker ctx->Feedback.Buffer = NULL;
664*61046927SAndroid Build Coastguard Worker ctx->Feedback.BufferSize = 0;
665*61046927SAndroid Build Coastguard Worker ctx->Feedback.Count = 0;
666*61046927SAndroid Build Coastguard Worker
667*61046927SAndroid Build Coastguard Worker /* Selection/picking */
668*61046927SAndroid Build Coastguard Worker ctx->Select.Buffer = NULL;
669*61046927SAndroid Build Coastguard Worker ctx->Select.BufferSize = 0;
670*61046927SAndroid Build Coastguard Worker ctx->Select.BufferCount = 0;
671*61046927SAndroid Build Coastguard Worker ctx->Select.Hits = 0;
672*61046927SAndroid Build Coastguard Worker ctx->Select.NameStackDepth = 0;
673*61046927SAndroid Build Coastguard Worker
674*61046927SAndroid Build Coastguard Worker /* Miscellaneous */
675*61046927SAndroid Build Coastguard Worker ctx->RenderMode = GL_RENDER;
676*61046927SAndroid Build Coastguard Worker }
677*61046927SAndroid Build Coastguard Worker
_mesa_free_feedback(struct gl_context * ctx)678*61046927SAndroid Build Coastguard Worker void _mesa_free_feedback(struct gl_context * ctx)
679*61046927SAndroid Build Coastguard Worker {
680*61046927SAndroid Build Coastguard Worker struct gl_selection *s = &ctx->Select;
681*61046927SAndroid Build Coastguard Worker
682*61046927SAndroid Build Coastguard Worker free(s->SaveBuffer);
683*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &s->Result, NULL);
684*61046927SAndroid Build Coastguard Worker }
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker /*@}*/
687