f7e922e2a22f8c91980b04c248cb5081f111fffe
2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 _mesa_ClearIndex( GLfloat c
)
43 GET_CURRENT_CONTEXT(ctx
);
44 ASSERT_OUTSIDE_BEGIN_END(ctx
);
46 if (ctx
->Color
.ClearIndex
== (GLuint
) c
)
49 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
50 ctx
->Color
.ClearIndex
= (GLuint
) c
;
52 if (!ctx
->Visual
.rgbMode
&& ctx
->Driver
.ClearIndex
) {
53 /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
54 (*ctx
->Driver
.ClearIndex
)( ctx
, ctx
->Color
.ClearIndex
);
61 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
64 GET_CURRENT_CONTEXT(ctx
);
65 ASSERT_OUTSIDE_BEGIN_END(ctx
);
67 tmp
[0] = CLAMP(red
, 0.0F
, 1.0F
);
68 tmp
[1] = CLAMP(green
, 0.0F
, 1.0F
);
69 tmp
[2] = CLAMP(blue
, 0.0F
, 1.0F
);
70 tmp
[3] = CLAMP(alpha
, 0.0F
, 1.0F
);
72 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
))
73 return; /* no change */
75 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
76 COPY_4V(ctx
->Color
.ClearColor
, tmp
);
78 if (ctx
->Visual
.rgbMode
&& ctx
->Driver
.ClearColor
) {
79 /* it's OK to call glClearColor in CI mode but it should be a NOP */
80 (*ctx
->Driver
.ClearColor
)(ctx
, ctx
->Color
.ClearColor
);
87 _mesa_Clear( GLbitfield mask
)
89 GET_CURRENT_CONTEXT(ctx
);
90 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
92 if (MESA_VERBOSE
& VERBOSE_API
)
93 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
95 if (mask
& ~(GL_COLOR_BUFFER_BIT
|
97 GL_STENCIL_BUFFER_BIT
|
98 GL_ACCUM_BUFFER_BIT
)) {
100 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(mask)");
105 _mesa_update_state( ctx
); /* update _Xmin, etc */
108 if (ctx
->RenderMode
==GL_RENDER
) {
109 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
110 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
111 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
112 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
115 /* don't clear depth buffer if depth writing disabled */
116 if (!ctx
->Depth
.Mask
)
117 mask
&= ~GL_DEPTH_BUFFER_BIT
;
119 /* Build the bitmask to send to device driver's Clear function.
120 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
121 * of the FRONT/BACK_LEFT/RIGHT_BIT flags.
124 if (mask
& GL_COLOR_BUFFER_BIT
)
125 ddMask
|= ctx
->Color
._DrawDestMask
;
126 if ((mask
& GL_DEPTH_BUFFER_BIT
) && ctx
->Visual
.depthBits
> 0)
127 ddMask
|= GL_DEPTH_BUFFER_BIT
;
128 if ((mask
& GL_STENCIL_BUFFER_BIT
) && ctx
->Visual
.stencilBits
> 0)
129 ddMask
|= GL_STENCIL_BUFFER_BIT
;
130 if ((mask
& GL_ACCUM_BUFFER_BIT
) && ctx
->Visual
.accumRedBits
> 0)
131 ddMask
|= GL_ACCUM_BUFFER_BIT
;
133 ASSERT(ctx
->Driver
.Clear
);
134 ctx
->Driver
.Clear( ctx
, ddMask
, (GLboolean
) !ctx
->Scissor
.Enabled
,
135 x
, y
, width
, height
);
141 _mesa_DrawBuffer( GLenum mode
)
143 GET_CURRENT_CONTEXT(ctx
);
144 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* too complex... */
146 if (MESA_VERBOSE
& VERBOSE_API
)
147 _mesa_debug(ctx
, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode
));
150 * Do error checking and compute the _DrawDestMask bitfield.
154 if (!ctx
->Visual
.stereoMode
) {
155 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
157 if (ctx
->Visual
.doubleBufferMode
)
158 ctx
->Color
._DrawDestMask
= FRONT_RIGHT_BIT
| BACK_RIGHT_BIT
;
160 ctx
->Color
._DrawDestMask
= FRONT_RIGHT_BIT
;
163 if (!ctx
->Visual
.stereoMode
) {
164 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
167 ctx
->Color
._DrawDestMask
= FRONT_RIGHT_BIT
;
170 if (!ctx
->Visual
.stereoMode
|| !ctx
->Visual
.doubleBufferMode
) {
171 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
174 ctx
->Color
._DrawDestMask
= BACK_RIGHT_BIT
;
177 if (!ctx
->Visual
.doubleBufferMode
) {
178 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
181 ctx
->Color
._DrawDestMask
= BACK_LEFT_BIT
;
183 case GL_FRONT_AND_BACK
:
184 if (!ctx
->Visual
.doubleBufferMode
) {
185 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
188 if (ctx
->Visual
.stereoMode
)
189 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
| BACK_LEFT_BIT
190 | FRONT_RIGHT_BIT
| BACK_RIGHT_BIT
;
192 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
| BACK_LEFT_BIT
;
195 if (!ctx
->Visual
.doubleBufferMode
) {
196 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
199 if (ctx
->Visual
.stereoMode
)
200 ctx
->Color
._DrawDestMask
= BACK_LEFT_BIT
| BACK_RIGHT_BIT
;
202 ctx
->Color
._DrawDestMask
= BACK_LEFT_BIT
;
206 if (ctx
->Visual
.doubleBufferMode
)
207 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
| BACK_LEFT_BIT
;
209 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
;
213 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
;
217 if (ctx
->Visual
.stereoMode
)
218 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
| FRONT_RIGHT_BIT
;
220 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
;
224 ctx
->Color
._DrawDestMask
= 0;
227 if (ctx
->Const
.NumAuxBuffers
>= 1) {
228 ctx
->Color
._DrawDestMask
= AUX0_BIT
;
231 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer(GL_AUX0)" );
236 if (ctx
->Const
.NumAuxBuffers
>= 2) {
237 ctx
->Color
._DrawDestMask
= AUX1_BIT
;
240 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer(GL_AUX1)" );
245 if (ctx
->Const
.NumAuxBuffers
>= 3) {
246 ctx
->Color
._DrawDestMask
= AUX2_BIT
;
249 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer(GL_AUX2)" );
254 if (ctx
->Const
.NumAuxBuffers
>= 4) {
255 ctx
->Color
._DrawDestMask
= AUX3_BIT
;
258 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer(GL_AUX3)" );
263 _mesa_error( ctx
, GL_INVALID_ENUM
, "glDrawBuffer" );
267 ctx
->Color
.DrawBuffer
= mode
;
268 ctx
->NewState
|= _NEW_COLOR
;
271 * Call device driver function.
273 if (ctx
->Driver
.DrawBuffer
)
274 (*ctx
->Driver
.DrawBuffer
)(ctx
, mode
);
280 _mesa_ReadBuffer( GLenum mode
)
282 GET_CURRENT_CONTEXT(ctx
);
283 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
285 if (MESA_VERBOSE
& VERBOSE_API
)
286 _mesa_debug(ctx
, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode
));
289 * Do error checking and compute ctx->Pixel._ReadSrcMask.
295 /* Front-Left buffer, always exists */
296 ctx
->Pixel
._ReadSrcMask
= FRONT_LEFT_BIT
;
300 /* Back-Left buffer, requires double buffering */
301 if (!ctx
->Visual
.doubleBufferMode
) {
302 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
305 ctx
->Pixel
._ReadSrcMask
= BACK_LEFT_BIT
;
309 if (!ctx
->Visual
.stereoMode
) {
310 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
313 ctx
->Pixel
._ReadSrcMask
= FRONT_RIGHT_BIT
;
316 if (!ctx
->Visual
.stereoMode
|| !ctx
->Visual
.doubleBufferMode
) {
317 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
320 ctx
->Pixel
._ReadSrcMask
= BACK_RIGHT_BIT
;
323 if (ctx
->Const
.NumAuxBuffers
>= 1) {
324 ctx
->Pixel
._ReadSrcMask
= AUX0_BIT
;
327 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer(GL_AUX0)" );
332 if (ctx
->Const
.NumAuxBuffers
>= 2) {
333 ctx
->Pixel
._ReadSrcMask
= AUX1_BIT
;
336 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer(GL_AUX1)" );
341 if (ctx
->Const
.NumAuxBuffers
>= 3) {
342 ctx
->Pixel
._ReadSrcMask
= AUX2_BIT
;
345 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer(GL_AUX2)" );
350 if (ctx
->Const
.NumAuxBuffers
>= 4) {
351 ctx
->Pixel
._ReadSrcMask
= AUX3_BIT
;
354 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer(GL_AUX3)" );
359 _mesa_error( ctx
, GL_INVALID_ENUM
, "glReadBuffer" );
363 ctx
->Pixel
.ReadBuffer
= mode
;
364 ctx
->NewState
|= _NEW_PIXEL
;
367 * Call device driver function.
369 if (ctx
->Driver
.ReadBuffer
)
370 (*ctx
->Driver
.ReadBuffer
)(ctx
, mode
);
375 * GL_MESA_resize_buffers extension
376 * When this function is called, we'll ask the window system how large
377 * the current window is. If it's not what we expect, we'll have to
378 * resize/reallocate the software accum/stencil/depth/alpha buffers.
381 _mesa_ResizeBuffersMESA( void )
383 GLcontext
*ctx
= _mesa_get_current_context();
385 if (MESA_VERBOSE
& VERBOSE_API
)
386 _mesa_debug(ctx
, "glResizeBuffersMESA\n");
389 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx
);
391 if (ctx
->DrawBuffer
) {
392 GLuint buf_width
, buf_height
;
393 GLframebuffer
*buffer
= ctx
->DrawBuffer
;
395 /* ask device driver for size of output buffer */
396 (*ctx
->Driver
.GetBufferSize
)( buffer
, &buf_width
, &buf_height
);
398 /* see if size of device driver's color buffer (window) has changed */
399 if (buffer
->Width
== buf_width
&& buffer
->Height
== buf_height
)
400 return; /* size is as expected */
402 buffer
->Width
= buf_width
;
403 buffer
->Height
= buf_height
;
405 ctx
->Driver
.ResizeBuffers( buffer
);
408 if (ctx
->ReadBuffer
&& ctx
->ReadBuffer
!= ctx
->DrawBuffer
) {
409 GLuint buf_width
, buf_height
;
410 GLframebuffer
*buffer
= ctx
->DrawBuffer
;
412 /* ask device driver for size of output buffer */
413 (*ctx
->Driver
.GetBufferSize
)( buffer
, &buf_width
, &buf_height
);
415 /* see if size of device driver's color buffer (window) has changed */
416 if (buffer
->Width
== buf_width
&& buffer
->Height
== buf_height
)
417 return; /* size is as expected */
419 buffer
->Width
= buf_width
;
420 buffer
->Height
= buf_height
;
422 ctx
->Driver
.ResizeBuffers( buffer
);
425 ctx
->NewState
|= _NEW_BUFFERS
; /* to update scissor / window bounds */
431 _mesa_Scissor( GLint x
, GLint y
, GLsizei width
, GLsizei height
)
433 GET_CURRENT_CONTEXT(ctx
);
434 ASSERT_OUTSIDE_BEGIN_END(ctx
);
436 if (width
< 0 || height
< 0) {
437 _mesa_error( ctx
, GL_INVALID_VALUE
, "glScissor" );
441 if (MESA_VERBOSE
& VERBOSE_API
)
442 _mesa_debug(ctx
, "glScissor %d %d %d %d\n", x
, y
, width
, height
);
444 if (x
== ctx
->Scissor
.X
&&
445 y
== ctx
->Scissor
.Y
&&
446 width
== ctx
->Scissor
.Width
&&
447 height
== ctx
->Scissor
.Height
)
450 FLUSH_VERTICES(ctx
, _NEW_SCISSOR
);
453 ctx
->Scissor
.Width
= width
;
454 ctx
->Scissor
.Height
= height
;
456 if (ctx
->Driver
.Scissor
)
457 ctx
->Driver
.Scissor( ctx
, x
, y
, width
, height
);
462 * XXX move somewhere else someday?
465 _mesa_SampleCoverageARB(GLclampf value
, GLboolean invert
)
467 GLcontext
*ctx
= _mesa_get_current_context();
469 if (!ctx
->Extensions
.ARB_multisample
) {
470 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glSampleCoverageARB");
474 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx
);
475 ctx
->Multisample
.SampleCoverageValue
= (GLfloat
) CLAMP(value
, 0.0, 1.0);
476 ctx
->Multisample
.SampleCoverageInvert
= invert
;
477 ctx
->NewState
|= _NEW_MULTISAMPLE
;