xref: /aosp_15_r20/external/mesa3d/src/mesa/main/clear.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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-2007  Brian Paul   All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker  *
13*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker  *
16*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker  */
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker /**
27*61046927SAndroid Build Coastguard Worker  * \file clear.c
28*61046927SAndroid Build Coastguard Worker  * glClearColor, glClearIndex, glClear() functions.
29*61046927SAndroid Build Coastguard Worker  */
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker #include "glformats.h"
34*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
35*61046927SAndroid Build Coastguard Worker #include "context.h"
36*61046927SAndroid Build Coastguard Worker #include "enums.h"
37*61046927SAndroid Build Coastguard Worker #include "fbobject.h"
38*61046927SAndroid Build Coastguard Worker #include "get.h"
39*61046927SAndroid Build Coastguard Worker #include "macros.h"
40*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
41*61046927SAndroid Build Coastguard Worker #include "state.h"
42*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_clear.h"
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearIndex(GLfloat c)47*61046927SAndroid Build Coastguard Worker _mesa_ClearIndex( GLfloat c )
48*61046927SAndroid Build Coastguard Worker {
49*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker    ctx->PopAttribState |= GL_COLOR_BUFFER_BIT;
52*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearIndex = (GLuint) c;
53*61046927SAndroid Build Coastguard Worker }
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker /**
57*61046927SAndroid Build Coastguard Worker  * Specify the clear values for the color buffers.
58*61046927SAndroid Build Coastguard Worker  *
59*61046927SAndroid Build Coastguard Worker  * \param red red color component.
60*61046927SAndroid Build Coastguard Worker  * \param green green color component.
61*61046927SAndroid Build Coastguard Worker  * \param blue blue color component.
62*61046927SAndroid Build Coastguard Worker  * \param alpha alpha component.
63*61046927SAndroid Build Coastguard Worker  *
64*61046927SAndroid Build Coastguard Worker  * \sa glClearColor().
65*61046927SAndroid Build Coastguard Worker  */
66*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)67*61046927SAndroid Build Coastguard Worker _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker    ctx->PopAttribState |= GL_COLOR_BUFFER_BIT;
72*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.f[0] = red;
73*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.f[1] = green;
74*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.f[2] = blue;
75*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.f[3] = alpha;
76*61046927SAndroid Build Coastguard Worker }
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker /**
80*61046927SAndroid Build Coastguard Worker  * GL_EXT_texture_integer
81*61046927SAndroid Build Coastguard Worker  */
82*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearColorIiEXT(GLint r,GLint g,GLint b,GLint a)83*61046927SAndroid Build Coastguard Worker _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    ctx->PopAttribState |= GL_COLOR_BUFFER_BIT;
88*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.i[0] = r;
89*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.i[1] = g;
90*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.i[2] = b;
91*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.i[3] = a;
92*61046927SAndroid Build Coastguard Worker }
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker /**
96*61046927SAndroid Build Coastguard Worker  * GL_EXT_texture_integer
97*61046927SAndroid Build Coastguard Worker  */
98*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearColorIuiEXT(GLuint r,GLuint g,GLuint b,GLuint a)99*61046927SAndroid Build Coastguard Worker _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
100*61046927SAndroid Build Coastguard Worker {
101*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    ctx->PopAttribState |= GL_COLOR_BUFFER_BIT;
104*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.ui[0] = r;
105*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.ui[1] = g;
106*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.ui[2] = b;
107*61046927SAndroid Build Coastguard Worker    ctx->Color.ClearColor.ui[3] = a;
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  * Returns true if color writes are enabled for the given color attachment.
113*61046927SAndroid Build Coastguard Worker  *
114*61046927SAndroid Build Coastguard Worker  * Beyond checking ColorMask, this uses _mesa_format_has_color_component to
115*61046927SAndroid Build Coastguard Worker  * ignore components that don't actually exist in the format (such as X in
116*61046927SAndroid Build Coastguard Worker  * XRGB).
117*61046927SAndroid Build Coastguard Worker  */
118*61046927SAndroid Build Coastguard Worker static bool
color_buffer_writes_enabled(const struct gl_context * ctx,unsigned idx)119*61046927SAndroid Build Coastguard Worker color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx)
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx];
122*61046927SAndroid Build Coastguard Worker    GLuint c;
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    if (rb) {
125*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; c++) {
126*61046927SAndroid Build Coastguard Worker          if (GET_COLORMASK_BIT(ctx->Color.ColorMask, idx, c) &&
127*61046927SAndroid Build Coastguard Worker              _mesa_format_has_color_component(rb->Format, c)) {
128*61046927SAndroid Build Coastguard Worker             return true;
129*61046927SAndroid Build Coastguard Worker          }
130*61046927SAndroid Build Coastguard Worker       }
131*61046927SAndroid Build Coastguard Worker    }
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker    return false;
134*61046927SAndroid Build Coastguard Worker }
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker /**
138*61046927SAndroid Build Coastguard Worker  * Clear buffers.
139*61046927SAndroid Build Coastguard Worker  *
140*61046927SAndroid Build Coastguard Worker  * \param mask bit-mask indicating the buffers to be cleared.
141*61046927SAndroid Build Coastguard Worker  *
142*61046927SAndroid Build Coastguard Worker  * Flushes the vertices and verifies the parameter.
143*61046927SAndroid Build Coastguard Worker  * If __struct gl_contextRec::NewState is set then calls _mesa_update_clear_state()
144*61046927SAndroid Build Coastguard Worker  * to update gl_frame_buffer::_Xmin, etc.  If the rasterization mode is set to
145*61046927SAndroid Build Coastguard Worker  * GL_RENDER then requests the driver to clear the buffers, via the
146*61046927SAndroid Build Coastguard Worker  * dd_function_table::Clear callback.
147*61046927SAndroid Build Coastguard Worker  */
148*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clear(struct gl_context * ctx,GLbitfield mask,bool no_error)149*61046927SAndroid Build Coastguard Worker clear(struct gl_context *ctx, GLbitfield mask, bool no_error)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker    if (!no_error) {
154*61046927SAndroid Build Coastguard Worker       if (mask & ~(GL_COLOR_BUFFER_BIT |
155*61046927SAndroid Build Coastguard Worker                    GL_DEPTH_BUFFER_BIT |
156*61046927SAndroid Build Coastguard Worker                    GL_STENCIL_BUFFER_BIT |
157*61046927SAndroid Build Coastguard Worker                    GL_ACCUM_BUFFER_BIT)) {
158*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
159*61046927SAndroid Build Coastguard Worker          return;
160*61046927SAndroid Build Coastguard Worker       }
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker       /* Accumulation buffers were removed in core contexts, and they never
163*61046927SAndroid Build Coastguard Worker        * existed in OpenGL ES.
164*61046927SAndroid Build Coastguard Worker        */
165*61046927SAndroid Build Coastguard Worker       if ((mask & GL_ACCUM_BUFFER_BIT) != 0
166*61046927SAndroid Build Coastguard Worker           && (_mesa_is_desktop_gl_core(ctx) || _mesa_is_gles(ctx))) {
167*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
168*61046927SAndroid Build Coastguard Worker          return;
169*61046927SAndroid Build Coastguard Worker       }
170*61046927SAndroid Build Coastguard Worker    }
171*61046927SAndroid Build Coastguard Worker 
172*61046927SAndroid Build Coastguard Worker    if (ctx->NewState) {
173*61046927SAndroid Build Coastguard Worker       _mesa_update_clear_state( ctx );	/* update _Xmin, etc */
174*61046927SAndroid Build Coastguard Worker    }
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
177*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
178*61046927SAndroid Build Coastguard Worker                   "glClear(incomplete framebuffer)");
179*61046927SAndroid Build Coastguard Worker       return;
180*61046927SAndroid Build Coastguard Worker    }
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    if (ctx->RasterDiscard)
183*61046927SAndroid Build Coastguard Worker       return;
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    if (ctx->RenderMode == GL_RENDER) {
186*61046927SAndroid Build Coastguard Worker       GLbitfield bufferMask;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker       /* don't clear depth buffer if depth writing disabled */
189*61046927SAndroid Build Coastguard Worker       if (!ctx->Depth.Mask)
190*61046927SAndroid Build Coastguard Worker          mask &= ~GL_DEPTH_BUFFER_BIT;
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker       /* Build the bitmask to send to device driver's Clear function.
193*61046927SAndroid Build Coastguard Worker        * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
194*61046927SAndroid Build Coastguard Worker        * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
195*61046927SAndroid Build Coastguard Worker        * BUFFER_BIT_COLORn flags.
196*61046927SAndroid Build Coastguard Worker        */
197*61046927SAndroid Build Coastguard Worker       bufferMask = 0;
198*61046927SAndroid Build Coastguard Worker       if (mask & GL_COLOR_BUFFER_BIT) {
199*61046927SAndroid Build Coastguard Worker          GLuint i;
200*61046927SAndroid Build Coastguard Worker          for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
201*61046927SAndroid Build Coastguard Worker             gl_buffer_index buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker             if (buf != BUFFER_NONE && color_buffer_writes_enabled(ctx, i)) {
204*61046927SAndroid Build Coastguard Worker                bufferMask |= 1 << buf;
205*61046927SAndroid Build Coastguard Worker             }
206*61046927SAndroid Build Coastguard Worker          }
207*61046927SAndroid Build Coastguard Worker       }
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker       if ((mask & GL_DEPTH_BUFFER_BIT)
210*61046927SAndroid Build Coastguard Worker           && ctx->DrawBuffer->Visual.depthBits > 0) {
211*61046927SAndroid Build Coastguard Worker          bufferMask |= BUFFER_BIT_DEPTH;
212*61046927SAndroid Build Coastguard Worker       }
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker       if ((mask & GL_STENCIL_BUFFER_BIT)
215*61046927SAndroid Build Coastguard Worker           && ctx->DrawBuffer->Visual.stencilBits > 0) {
216*61046927SAndroid Build Coastguard Worker          bufferMask |= BUFFER_BIT_STENCIL;
217*61046927SAndroid Build Coastguard Worker       }
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker       if ((mask & GL_ACCUM_BUFFER_BIT)
220*61046927SAndroid Build Coastguard Worker           && ctx->DrawBuffer->Visual.accumRedBits > 0) {
221*61046927SAndroid Build Coastguard Worker          bufferMask |= BUFFER_BIT_ACCUM;
222*61046927SAndroid Build Coastguard Worker       }
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker       st_Clear(ctx, bufferMask);
225*61046927SAndroid Build Coastguard Worker    }
226*61046927SAndroid Build Coastguard Worker }
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Clear_no_error(GLbitfield mask)230*61046927SAndroid Build Coastguard Worker _mesa_Clear_no_error(GLbitfield mask)
231*61046927SAndroid Build Coastguard Worker {
232*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
233*61046927SAndroid Build Coastguard Worker    clear(ctx, mask, true);
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Clear(GLbitfield mask)238*61046927SAndroid Build Coastguard Worker _mesa_Clear(GLbitfield mask)
239*61046927SAndroid Build Coastguard Worker {
240*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
241*61046927SAndroid Build Coastguard Worker 
242*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API)
243*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glClear 0x%x\n", mask);
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker    clear(ctx, mask, false);
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker /** Returned by make_color_buffer_mask() for errors */
250*61046927SAndroid Build Coastguard Worker #define INVALID_MASK ~0x0U
251*61046927SAndroid Build Coastguard Worker 
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker /**
254*61046927SAndroid Build Coastguard Worker  * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
255*61046927SAndroid Build Coastguard Worker  * BUFFER_BIT_x values.
256*61046927SAndroid Build Coastguard Worker  * Return INVALID_MASK if the drawbuffer value is invalid.
257*61046927SAndroid Build Coastguard Worker  */
258*61046927SAndroid Build Coastguard Worker static GLbitfield
make_color_buffer_mask(struct gl_context * ctx,GLint drawbuffer)259*61046927SAndroid Build Coastguard Worker make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
260*61046927SAndroid Build Coastguard Worker {
261*61046927SAndroid Build Coastguard Worker    const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
262*61046927SAndroid Build Coastguard Worker    GLbitfield mask = 0x0;
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker    /* From the GL 4.0 specification:
265*61046927SAndroid Build Coastguard Worker     *	If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
266*61046927SAndroid Build Coastguard Worker     *	specified by passing i as the parameter drawbuffer, and value
267*61046927SAndroid Build Coastguard Worker     *	points to a four-element vector specifying the R, G, B, and A
268*61046927SAndroid Build Coastguard Worker     *	color to clear that draw buffer to. If the draw buffer is one
269*61046927SAndroid Build Coastguard Worker     *	of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
270*61046927SAndroid Build Coastguard Worker     *	multiple buffers, each selected buffer is cleared to the same
271*61046927SAndroid Build Coastguard Worker     *	value.
272*61046927SAndroid Build Coastguard Worker     *
273*61046927SAndroid Build Coastguard Worker     * Note that "drawbuffer" and "draw buffer" have different meaning.
274*61046927SAndroid Build Coastguard Worker     * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
275*61046927SAndroid Build Coastguard Worker     * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
276*61046927SAndroid Build Coastguard Worker     * etc.
277*61046927SAndroid Build Coastguard Worker     */
278*61046927SAndroid Build Coastguard Worker    if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
279*61046927SAndroid Build Coastguard Worker       return INVALID_MASK;
280*61046927SAndroid Build Coastguard Worker    }
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker    switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) {
283*61046927SAndroid Build Coastguard Worker    case GL_FRONT:
284*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
285*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_FRONT_LEFT;
286*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
287*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_FRONT_RIGHT;
288*61046927SAndroid Build Coastguard Worker       break;
289*61046927SAndroid Build Coastguard Worker    case GL_BACK:
290*61046927SAndroid Build Coastguard Worker       /* For GLES contexts with a single buffered configuration, we actually
291*61046927SAndroid Build Coastguard Worker        * only have a front renderbuffer, so any clear calls to GL_BACK should
292*61046927SAndroid Build Coastguard Worker        * affect that buffer. See draw_buffer_enum_to_bitmask for details.
293*61046927SAndroid Build Coastguard Worker        */
294*61046927SAndroid Build Coastguard Worker       if (_mesa_is_gles(ctx))
295*61046927SAndroid Build Coastguard Worker          if (!ctx->DrawBuffer->Visual.doubleBufferMode)
296*61046927SAndroid Build Coastguard Worker             if (att[BUFFER_FRONT_LEFT].Renderbuffer)
297*61046927SAndroid Build Coastguard Worker                mask |= BUFFER_BIT_FRONT_LEFT;
298*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_BACK_LEFT].Renderbuffer)
299*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_BACK_LEFT;
300*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
301*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_BACK_RIGHT;
302*61046927SAndroid Build Coastguard Worker       break;
303*61046927SAndroid Build Coastguard Worker    case GL_LEFT:
304*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
305*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_FRONT_LEFT;
306*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_BACK_LEFT].Renderbuffer)
307*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_BACK_LEFT;
308*61046927SAndroid Build Coastguard Worker       break;
309*61046927SAndroid Build Coastguard Worker    case GL_RIGHT:
310*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
311*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_FRONT_RIGHT;
312*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
313*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_BACK_RIGHT;
314*61046927SAndroid Build Coastguard Worker       break;
315*61046927SAndroid Build Coastguard Worker    case GL_FRONT_AND_BACK:
316*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
317*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_FRONT_LEFT;
318*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_BACK_LEFT].Renderbuffer)
319*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_BACK_LEFT;
320*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
321*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_FRONT_RIGHT;
322*61046927SAndroid Build Coastguard Worker       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
323*61046927SAndroid Build Coastguard Worker          mask |= BUFFER_BIT_BACK_RIGHT;
324*61046927SAndroid Build Coastguard Worker       break;
325*61046927SAndroid Build Coastguard Worker    default:
326*61046927SAndroid Build Coastguard Worker       {
327*61046927SAndroid Build Coastguard Worker          gl_buffer_index buf =
328*61046927SAndroid Build Coastguard Worker             ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker          if (buf != BUFFER_NONE && att[buf].Renderbuffer) {
331*61046927SAndroid Build Coastguard Worker             mask |= 1 << buf;
332*61046927SAndroid Build Coastguard Worker          }
333*61046927SAndroid Build Coastguard Worker       }
334*61046927SAndroid Build Coastguard Worker    }
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker    return mask;
337*61046927SAndroid Build Coastguard Worker }
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker /**
342*61046927SAndroid Build Coastguard Worker  * New in GL 3.0
343*61046927SAndroid Build Coastguard Worker  * Clear signed integer color buffer or stencil buffer (not depth).
344*61046927SAndroid Build Coastguard Worker  */
345*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clear_bufferiv(struct gl_context * ctx,GLenum buffer,GLint drawbuffer,const GLint * value,bool no_error)346*61046927SAndroid Build Coastguard Worker clear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
347*61046927SAndroid Build Coastguard Worker                const GLint *value, bool no_error)
348*61046927SAndroid Build Coastguard Worker {
349*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker    if (ctx->NewState) {
352*61046927SAndroid Build Coastguard Worker       _mesa_update_clear_state( ctx );
353*61046927SAndroid Build Coastguard Worker    }
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker    if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
356*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
357*61046927SAndroid Build Coastguard Worker                   "glClearBufferiv(incomplete framebuffer)");
358*61046927SAndroid Build Coastguard Worker       return;
359*61046927SAndroid Build Coastguard Worker    }
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker    switch (buffer) {
362*61046927SAndroid Build Coastguard Worker    case GL_STENCIL:
363*61046927SAndroid Build Coastguard Worker       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
364*61046927SAndroid Build Coastguard Worker        *
365*61046927SAndroid Build Coastguard Worker        *     "ClearBuffer generates an INVALID VALUE error if buffer is
366*61046927SAndroid Build Coastguard Worker        *     COLOR and drawbuffer is less than zero, or greater than the
367*61046927SAndroid Build Coastguard Worker        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
368*61046927SAndroid Build Coastguard Worker        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
369*61046927SAndroid Build Coastguard Worker        */
370*61046927SAndroid Build Coastguard Worker       if (!no_error && drawbuffer != 0) {
371*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
372*61046927SAndroid Build Coastguard Worker                      drawbuffer);
373*61046927SAndroid Build Coastguard Worker          return;
374*61046927SAndroid Build Coastguard Worker       }
375*61046927SAndroid Build Coastguard Worker       else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer
376*61046927SAndroid Build Coastguard Worker                && !ctx->RasterDiscard) {
377*61046927SAndroid Build Coastguard Worker          /* Save current stencil clear value, set to 'value', do the
378*61046927SAndroid Build Coastguard Worker           * stencil clear and restore the clear value.
379*61046927SAndroid Build Coastguard Worker           * XXX in the future we may have a new st_ClearBuffer()
380*61046927SAndroid Build Coastguard Worker           * hook instead.
381*61046927SAndroid Build Coastguard Worker           */
382*61046927SAndroid Build Coastguard Worker          const GLuint clearSave = ctx->Stencil.Clear;
383*61046927SAndroid Build Coastguard Worker          ctx->Stencil.Clear = *value;
384*61046927SAndroid Build Coastguard Worker          st_Clear(ctx, BUFFER_BIT_STENCIL);
385*61046927SAndroid Build Coastguard Worker          ctx->Stencil.Clear = clearSave;
386*61046927SAndroid Build Coastguard Worker       }
387*61046927SAndroid Build Coastguard Worker       break;
388*61046927SAndroid Build Coastguard Worker    case GL_COLOR:
389*61046927SAndroid Build Coastguard Worker       {
390*61046927SAndroid Build Coastguard Worker          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
391*61046927SAndroid Build Coastguard Worker          if (!no_error && mask == INVALID_MASK) {
392*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
393*61046927SAndroid Build Coastguard Worker                         drawbuffer);
394*61046927SAndroid Build Coastguard Worker             return;
395*61046927SAndroid Build Coastguard Worker          }
396*61046927SAndroid Build Coastguard Worker          else if (mask && !ctx->RasterDiscard) {
397*61046927SAndroid Build Coastguard Worker             union gl_color_union clearSave;
398*61046927SAndroid Build Coastguard Worker 
399*61046927SAndroid Build Coastguard Worker             /* save color */
400*61046927SAndroid Build Coastguard Worker             clearSave = ctx->Color.ClearColor;
401*61046927SAndroid Build Coastguard Worker             /* set color */
402*61046927SAndroid Build Coastguard Worker             COPY_4V(ctx->Color.ClearColor.i, value);
403*61046927SAndroid Build Coastguard Worker             /* clear buffer(s) */
404*61046927SAndroid Build Coastguard Worker             st_Clear(ctx, mask);
405*61046927SAndroid Build Coastguard Worker             /* restore color */
406*61046927SAndroid Build Coastguard Worker             ctx->Color.ClearColor = clearSave;
407*61046927SAndroid Build Coastguard Worker          }
408*61046927SAndroid Build Coastguard Worker       }
409*61046927SAndroid Build Coastguard Worker       break;
410*61046927SAndroid Build Coastguard Worker    default:
411*61046927SAndroid Build Coastguard Worker       if (!no_error) {
412*61046927SAndroid Build Coastguard Worker          /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
413*61046927SAndroid Build Coastguard Worker           * of the OpenGL 4.5 spec states:
414*61046927SAndroid Build Coastguard Worker           *
415*61046927SAndroid Build Coastguard Worker           *    "An INVALID_ENUM error is generated by ClearBufferiv and
416*61046927SAndroid Build Coastguard Worker           *     ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
417*61046927SAndroid Build Coastguard Worker           */
418*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
419*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(buffer));
420*61046927SAndroid Build Coastguard Worker       }
421*61046927SAndroid Build Coastguard Worker       return;
422*61046927SAndroid Build Coastguard Worker    }
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker 
426*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferiv_no_error(GLenum buffer,GLint drawbuffer,const GLint * value)427*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferiv_no_error(GLenum buffer, GLint drawbuffer, const GLint *value)
428*61046927SAndroid Build Coastguard Worker {
429*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
430*61046927SAndroid Build Coastguard Worker    clear_bufferiv(ctx, buffer, drawbuffer, value, true);
431*61046927SAndroid Build Coastguard Worker }
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker 
434*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferiv(GLenum buffer,GLint drawbuffer,const GLint * value)435*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
438*61046927SAndroid Build Coastguard Worker    clear_bufferiv(ctx, buffer, drawbuffer, value, false);
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker 
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker /**
443*61046927SAndroid Build Coastguard Worker  * The ClearBuffer framework is so complicated and so riddled with the
444*61046927SAndroid Build Coastguard Worker  * assumption that the framebuffer is bound that, for now, we will just fake
445*61046927SAndroid Build Coastguard Worker  * direct state access clearing for the user.
446*61046927SAndroid Build Coastguard Worker  */
447*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedFramebufferiv(GLuint framebuffer,GLenum buffer,GLint drawbuffer,const GLint * value)448*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
449*61046927SAndroid Build Coastguard Worker                               GLint drawbuffer, const GLint *value)
450*61046927SAndroid Build Coastguard Worker {
451*61046927SAndroid Build Coastguard Worker    GLint oldfb;
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
454*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
455*61046927SAndroid Build Coastguard Worker    _mesa_ClearBufferiv(buffer, drawbuffer, value);
456*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
457*61046927SAndroid Build Coastguard Worker }
458*61046927SAndroid Build Coastguard Worker 
459*61046927SAndroid Build Coastguard Worker 
460*61046927SAndroid Build Coastguard Worker /**
461*61046927SAndroid Build Coastguard Worker  * New in GL 3.0
462*61046927SAndroid Build Coastguard Worker  * Clear unsigned integer color buffer (not depth, not stencil).
463*61046927SAndroid Build Coastguard Worker  */
464*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clear_bufferuiv(struct gl_context * ctx,GLenum buffer,GLint drawbuffer,const GLuint * value,bool no_error)465*61046927SAndroid Build Coastguard Worker clear_bufferuiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
466*61046927SAndroid Build Coastguard Worker                 const GLuint *value, bool no_error)
467*61046927SAndroid Build Coastguard Worker {
468*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
469*61046927SAndroid Build Coastguard Worker 
470*61046927SAndroid Build Coastguard Worker    if (ctx->NewState) {
471*61046927SAndroid Build Coastguard Worker       _mesa_update_clear_state( ctx );
472*61046927SAndroid Build Coastguard Worker    }
473*61046927SAndroid Build Coastguard Worker 
474*61046927SAndroid Build Coastguard Worker    if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
475*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
476*61046927SAndroid Build Coastguard Worker                   "glClearBufferuiv(incomplete framebuffer)");
477*61046927SAndroid Build Coastguard Worker       return;
478*61046927SAndroid Build Coastguard Worker    }
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker    switch (buffer) {
481*61046927SAndroid Build Coastguard Worker    case GL_COLOR:
482*61046927SAndroid Build Coastguard Worker       {
483*61046927SAndroid Build Coastguard Worker          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
484*61046927SAndroid Build Coastguard Worker          if (!no_error && mask == INVALID_MASK) {
485*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
486*61046927SAndroid Build Coastguard Worker                         drawbuffer);
487*61046927SAndroid Build Coastguard Worker             return;
488*61046927SAndroid Build Coastguard Worker          }
489*61046927SAndroid Build Coastguard Worker          else if (mask && !ctx->RasterDiscard) {
490*61046927SAndroid Build Coastguard Worker             union gl_color_union clearSave;
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker             /* save color */
493*61046927SAndroid Build Coastguard Worker             clearSave = ctx->Color.ClearColor;
494*61046927SAndroid Build Coastguard Worker             /* set color */
495*61046927SAndroid Build Coastguard Worker             COPY_4V(ctx->Color.ClearColor.ui, value);
496*61046927SAndroid Build Coastguard Worker             /* clear buffer(s) */
497*61046927SAndroid Build Coastguard Worker             st_Clear(ctx, mask);
498*61046927SAndroid Build Coastguard Worker             /* restore color */
499*61046927SAndroid Build Coastguard Worker             ctx->Color.ClearColor = clearSave;
500*61046927SAndroid Build Coastguard Worker          }
501*61046927SAndroid Build Coastguard Worker       }
502*61046927SAndroid Build Coastguard Worker       break;
503*61046927SAndroid Build Coastguard Worker    default:
504*61046927SAndroid Build Coastguard Worker       if (!no_error) {
505*61046927SAndroid Build Coastguard Worker          /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
506*61046927SAndroid Build Coastguard Worker           * of the OpenGL 4.5 spec states:
507*61046927SAndroid Build Coastguard Worker           *
508*61046927SAndroid Build Coastguard Worker           *    "An INVALID_ENUM error is generated by ClearBufferuiv and
509*61046927SAndroid Build Coastguard Worker           *     ClearNamedFramebufferuiv if buffer is not COLOR."
510*61046927SAndroid Build Coastguard Worker           */
511*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
512*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(buffer));
513*61046927SAndroid Build Coastguard Worker       }
514*61046927SAndroid Build Coastguard Worker       return;
515*61046927SAndroid Build Coastguard Worker    }
516*61046927SAndroid Build Coastguard Worker }
517*61046927SAndroid Build Coastguard Worker 
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferuiv_no_error(GLenum buffer,GLint drawbuffer,const GLuint * value)520*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferuiv_no_error(GLenum buffer, GLint drawbuffer,
521*61046927SAndroid Build Coastguard Worker                               const GLuint *value)
522*61046927SAndroid Build Coastguard Worker {
523*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
524*61046927SAndroid Build Coastguard Worker    clear_bufferuiv(ctx, buffer, drawbuffer, value, true);
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker 
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferuiv(GLenum buffer,GLint drawbuffer,const GLuint * value)529*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
530*61046927SAndroid Build Coastguard Worker {
531*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
532*61046927SAndroid Build Coastguard Worker    clear_bufferuiv(ctx, buffer, drawbuffer, value, false);
533*61046927SAndroid Build Coastguard Worker }
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker 
536*61046927SAndroid Build Coastguard Worker /**
537*61046927SAndroid Build Coastguard Worker  * The ClearBuffer framework is so complicated and so riddled with the
538*61046927SAndroid Build Coastguard Worker  * assumption that the framebuffer is bound that, for now, we will just fake
539*61046927SAndroid Build Coastguard Worker  * direct state access clearing for the user.
540*61046927SAndroid Build Coastguard Worker  */
541*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedFramebufferuiv(GLuint framebuffer,GLenum buffer,GLint drawbuffer,const GLuint * value)542*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
543*61046927SAndroid Build Coastguard Worker                                GLint drawbuffer, const GLuint *value)
544*61046927SAndroid Build Coastguard Worker {
545*61046927SAndroid Build Coastguard Worker    GLint oldfb;
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
548*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
549*61046927SAndroid Build Coastguard Worker    _mesa_ClearBufferuiv(buffer, drawbuffer, value);
550*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
551*61046927SAndroid Build Coastguard Worker }
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker /**
555*61046927SAndroid Build Coastguard Worker  * New in GL 3.0
556*61046927SAndroid Build Coastguard Worker  * Clear fixed-pt or float color buffer or depth buffer (not stencil).
557*61046927SAndroid Build Coastguard Worker  */
558*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clear_bufferfv(struct gl_context * ctx,GLenum buffer,GLint drawbuffer,const GLfloat * value,bool no_error)559*61046927SAndroid Build Coastguard Worker clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
560*61046927SAndroid Build Coastguard Worker                const GLfloat *value, bool no_error)
561*61046927SAndroid Build Coastguard Worker {
562*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker    if (ctx->NewState) {
565*61046927SAndroid Build Coastguard Worker       _mesa_update_clear_state( ctx );
566*61046927SAndroid Build Coastguard Worker    }
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker    if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
569*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
570*61046927SAndroid Build Coastguard Worker                   "glClearBufferfv(incomplete framebuffer)");
571*61046927SAndroid Build Coastguard Worker       return;
572*61046927SAndroid Build Coastguard Worker    }
573*61046927SAndroid Build Coastguard Worker 
574*61046927SAndroid Build Coastguard Worker    switch (buffer) {
575*61046927SAndroid Build Coastguard Worker    case GL_DEPTH:
576*61046927SAndroid Build Coastguard Worker       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
577*61046927SAndroid Build Coastguard Worker        *
578*61046927SAndroid Build Coastguard Worker        *     "ClearBuffer generates an INVALID VALUE error if buffer is
579*61046927SAndroid Build Coastguard Worker        *     COLOR and drawbuffer is less than zero, or greater than the
580*61046927SAndroid Build Coastguard Worker        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
581*61046927SAndroid Build Coastguard Worker        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
582*61046927SAndroid Build Coastguard Worker        */
583*61046927SAndroid Build Coastguard Worker       if (!no_error && drawbuffer != 0) {
584*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
585*61046927SAndroid Build Coastguard Worker                      drawbuffer);
586*61046927SAndroid Build Coastguard Worker          return;
587*61046927SAndroid Build Coastguard Worker       }
588*61046927SAndroid Build Coastguard Worker       else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer
589*61046927SAndroid Build Coastguard Worker                && !ctx->RasterDiscard) {
590*61046927SAndroid Build Coastguard Worker          /* Save current depth clear value, set to 'value', do the
591*61046927SAndroid Build Coastguard Worker           * depth clear and restore the clear value.
592*61046927SAndroid Build Coastguard Worker           * XXX in the future we may have a new st_ClearBuffer()
593*61046927SAndroid Build Coastguard Worker           * hook instead.
594*61046927SAndroid Build Coastguard Worker           */
595*61046927SAndroid Build Coastguard Worker          const GLclampd clearSave = ctx->Depth.Clear;
596*61046927SAndroid Build Coastguard Worker 
597*61046927SAndroid Build Coastguard Worker          /* Page 263 (page 279 of the PDF) of the OpenGL 3.0 spec says:
598*61046927SAndroid Build Coastguard Worker           *
599*61046927SAndroid Build Coastguard Worker           *     "If buffer is DEPTH, drawbuffer must be zero, and value points
600*61046927SAndroid Build Coastguard Worker           *     to the single depth value to clear the depth buffer to.
601*61046927SAndroid Build Coastguard Worker           *     Clamping and type conversion for fixed-point depth buffers are
602*61046927SAndroid Build Coastguard Worker           *     performed in the same fashion as for ClearDepth."
603*61046927SAndroid Build Coastguard Worker           */
604*61046927SAndroid Build Coastguard Worker          const struct gl_renderbuffer *rb =
605*61046927SAndroid Build Coastguard Worker             ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
606*61046927SAndroid Build Coastguard Worker          const bool is_float_depth =
607*61046927SAndroid Build Coastguard Worker             _mesa_has_depth_float_channel(rb->InternalFormat);
608*61046927SAndroid Build Coastguard Worker          ctx->Depth.Clear = is_float_depth ? *value : SATURATE(*value);
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker          st_Clear(ctx, BUFFER_BIT_DEPTH);
611*61046927SAndroid Build Coastguard Worker          ctx->Depth.Clear = clearSave;
612*61046927SAndroid Build Coastguard Worker       }
613*61046927SAndroid Build Coastguard Worker       /* clear depth buffer to value */
614*61046927SAndroid Build Coastguard Worker       break;
615*61046927SAndroid Build Coastguard Worker    case GL_COLOR:
616*61046927SAndroid Build Coastguard Worker       {
617*61046927SAndroid Build Coastguard Worker          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
618*61046927SAndroid Build Coastguard Worker          if (!no_error && mask == INVALID_MASK) {
619*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
620*61046927SAndroid Build Coastguard Worker                         drawbuffer);
621*61046927SAndroid Build Coastguard Worker             return;
622*61046927SAndroid Build Coastguard Worker          }
623*61046927SAndroid Build Coastguard Worker          else if (mask && !ctx->RasterDiscard) {
624*61046927SAndroid Build Coastguard Worker             union gl_color_union clearSave;
625*61046927SAndroid Build Coastguard Worker 
626*61046927SAndroid Build Coastguard Worker             /* save color */
627*61046927SAndroid Build Coastguard Worker             clearSave = ctx->Color.ClearColor;
628*61046927SAndroid Build Coastguard Worker             /* set color */
629*61046927SAndroid Build Coastguard Worker             COPY_4V(ctx->Color.ClearColor.f, value);
630*61046927SAndroid Build Coastguard Worker             /* clear buffer(s) */
631*61046927SAndroid Build Coastguard Worker             st_Clear(ctx, mask);
632*61046927SAndroid Build Coastguard Worker             /* restore color */
633*61046927SAndroid Build Coastguard Worker             ctx->Color.ClearColor = clearSave;
634*61046927SAndroid Build Coastguard Worker          }
635*61046927SAndroid Build Coastguard Worker       }
636*61046927SAndroid Build Coastguard Worker       break;
637*61046927SAndroid Build Coastguard Worker    default:
638*61046927SAndroid Build Coastguard Worker       if (!no_error) {
639*61046927SAndroid Build Coastguard Worker          /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
640*61046927SAndroid Build Coastguard Worker           * of the OpenGL 4.5 spec states:
641*61046927SAndroid Build Coastguard Worker           *
642*61046927SAndroid Build Coastguard Worker           *    "An INVALID_ENUM error is generated by ClearBufferfv and
643*61046927SAndroid Build Coastguard Worker           *     ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
644*61046927SAndroid Build Coastguard Worker           */
645*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
646*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(buffer));
647*61046927SAndroid Build Coastguard Worker       }
648*61046927SAndroid Build Coastguard Worker       return;
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 void GLAPIENTRY
_mesa_ClearBufferfv_no_error(GLenum buffer,GLint drawbuffer,const GLfloat * value)654*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferfv_no_error(GLenum buffer, GLint drawbuffer,
655*61046927SAndroid Build Coastguard Worker                              const GLfloat *value)
656*61046927SAndroid Build Coastguard Worker {
657*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
658*61046927SAndroid Build Coastguard Worker    clear_bufferfv(ctx, buffer, drawbuffer, value, true);
659*61046927SAndroid Build Coastguard Worker }
660*61046927SAndroid Build Coastguard Worker 
661*61046927SAndroid Build Coastguard Worker 
662*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferfv(GLenum buffer,GLint drawbuffer,const GLfloat * value)663*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
664*61046927SAndroid Build Coastguard Worker {
665*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
666*61046927SAndroid Build Coastguard Worker    clear_bufferfv(ctx, buffer, drawbuffer, value, false);
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker 
669*61046927SAndroid Build Coastguard Worker 
670*61046927SAndroid Build Coastguard Worker /**
671*61046927SAndroid Build Coastguard Worker  * The ClearBuffer framework is so complicated and so riddled with the
672*61046927SAndroid Build Coastguard Worker  * assumption that the framebuffer is bound that, for now, we will just fake
673*61046927SAndroid Build Coastguard Worker  * direct state access clearing for the user.
674*61046927SAndroid Build Coastguard Worker  */
675*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedFramebufferfv(GLuint framebuffer,GLenum buffer,GLint drawbuffer,const GLfloat * value)676*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
677*61046927SAndroid Build Coastguard Worker                               GLint drawbuffer, const GLfloat *value)
678*61046927SAndroid Build Coastguard Worker {
679*61046927SAndroid Build Coastguard Worker    GLint oldfb;
680*61046927SAndroid Build Coastguard Worker 
681*61046927SAndroid Build Coastguard Worker    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
682*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
683*61046927SAndroid Build Coastguard Worker    _mesa_ClearBufferfv(buffer, drawbuffer, value);
684*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
685*61046927SAndroid Build Coastguard Worker }
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker /**
689*61046927SAndroid Build Coastguard Worker  * New in GL 3.0
690*61046927SAndroid Build Coastguard Worker  * Clear depth/stencil buffer only.
691*61046927SAndroid Build Coastguard Worker  */
692*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clear_bufferfi(struct gl_context * ctx,GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil,bool no_error)693*61046927SAndroid Build Coastguard Worker clear_bufferfi(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
694*61046927SAndroid Build Coastguard Worker                GLfloat depth, GLint stencil, bool no_error)
695*61046927SAndroid Build Coastguard Worker {
696*61046927SAndroid Build Coastguard Worker    GLbitfield mask = 0;
697*61046927SAndroid Build Coastguard Worker 
698*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
699*61046927SAndroid Build Coastguard Worker 
700*61046927SAndroid Build Coastguard Worker    if (!no_error) {
701*61046927SAndroid Build Coastguard Worker       if (buffer != GL_DEPTH_STENCIL) {
702*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
703*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(buffer));
704*61046927SAndroid Build Coastguard Worker          return;
705*61046927SAndroid Build Coastguard Worker       }
706*61046927SAndroid Build Coastguard Worker 
707*61046927SAndroid Build Coastguard Worker       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
708*61046927SAndroid Build Coastguard Worker        *
709*61046927SAndroid Build Coastguard Worker        *     "ClearBuffer generates an INVALID VALUE error if buffer is
710*61046927SAndroid Build Coastguard Worker        *     COLOR and drawbuffer is less than zero, or greater than the
711*61046927SAndroid Build Coastguard Worker        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
712*61046927SAndroid Build Coastguard Worker        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
713*61046927SAndroid Build Coastguard Worker        */
714*61046927SAndroid Build Coastguard Worker       if (drawbuffer != 0) {
715*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
716*61046927SAndroid Build Coastguard Worker                      drawbuffer);
717*61046927SAndroid Build Coastguard Worker          return;
718*61046927SAndroid Build Coastguard Worker       }
719*61046927SAndroid Build Coastguard Worker    }
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker    if (ctx->RasterDiscard)
722*61046927SAndroid Build Coastguard Worker       return;
723*61046927SAndroid Build Coastguard Worker 
724*61046927SAndroid Build Coastguard Worker    if (ctx->NewState) {
725*61046927SAndroid Build Coastguard Worker       _mesa_update_clear_state( ctx );
726*61046927SAndroid Build Coastguard Worker    }
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker    if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
729*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
730*61046927SAndroid Build Coastguard Worker                   "glClearBufferfi(incomplete framebuffer)");
731*61046927SAndroid Build Coastguard Worker       return;
732*61046927SAndroid Build Coastguard Worker    }
733*61046927SAndroid Build Coastguard Worker 
734*61046927SAndroid Build Coastguard Worker    if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
735*61046927SAndroid Build Coastguard Worker       mask |= BUFFER_BIT_DEPTH;
736*61046927SAndroid Build Coastguard Worker    if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
737*61046927SAndroid Build Coastguard Worker       mask |= BUFFER_BIT_STENCIL;
738*61046927SAndroid Build Coastguard Worker 
739*61046927SAndroid Build Coastguard Worker    if (mask) {
740*61046927SAndroid Build Coastguard Worker       /* save current clear values */
741*61046927SAndroid Build Coastguard Worker       const GLclampd clearDepthSave = ctx->Depth.Clear;
742*61046927SAndroid Build Coastguard Worker       const GLuint clearStencilSave = ctx->Stencil.Clear;
743*61046927SAndroid Build Coastguard Worker 
744*61046927SAndroid Build Coastguard Worker       /* set new clear values
745*61046927SAndroid Build Coastguard Worker        *
746*61046927SAndroid Build Coastguard Worker        * Page 263 (page 279 of the PDF) of the OpenGL 3.0 spec says:
747*61046927SAndroid Build Coastguard Worker        *
748*61046927SAndroid Build Coastguard Worker        *     "depth and stencil are the values to clear the depth and stencil
749*61046927SAndroid Build Coastguard Worker        *     buffers to, respectively. Clamping and type conversion for
750*61046927SAndroid Build Coastguard Worker        *     fixed-point depth buffers are performed in the same fashion as
751*61046927SAndroid Build Coastguard Worker        *     for ClearDepth."
752*61046927SAndroid Build Coastguard Worker        */
753*61046927SAndroid Build Coastguard Worker       const struct gl_renderbuffer *rb =
754*61046927SAndroid Build Coastguard Worker          ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
755*61046927SAndroid Build Coastguard Worker       const bool has_float_depth = rb &&
756*61046927SAndroid Build Coastguard Worker          _mesa_has_depth_float_channel(rb->InternalFormat);
757*61046927SAndroid Build Coastguard Worker       ctx->Depth.Clear = has_float_depth ? depth : SATURATE(depth);
758*61046927SAndroid Build Coastguard Worker       ctx->Stencil.Clear = stencil;
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker       /* clear buffers */
761*61046927SAndroid Build Coastguard Worker       st_Clear(ctx, mask);
762*61046927SAndroid Build Coastguard Worker 
763*61046927SAndroid Build Coastguard Worker       /* restore */
764*61046927SAndroid Build Coastguard Worker       ctx->Depth.Clear = clearDepthSave;
765*61046927SAndroid Build Coastguard Worker       ctx->Stencil.Clear = clearStencilSave;
766*61046927SAndroid Build Coastguard Worker    }
767*61046927SAndroid Build Coastguard Worker }
768*61046927SAndroid Build Coastguard Worker 
769*61046927SAndroid Build Coastguard Worker 
770*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferfi_no_error(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)771*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferfi_no_error(GLenum buffer, GLint drawbuffer,
772*61046927SAndroid Build Coastguard Worker                              GLfloat depth, GLint stencil)
773*61046927SAndroid Build Coastguard Worker {
774*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
775*61046927SAndroid Build Coastguard Worker    clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, true);
776*61046927SAndroid Build Coastguard Worker }
777*61046927SAndroid Build Coastguard Worker 
778*61046927SAndroid Build Coastguard Worker 
779*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferfi(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)780*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
781*61046927SAndroid Build Coastguard Worker                     GLfloat depth, GLint stencil)
782*61046927SAndroid Build Coastguard Worker {
783*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
784*61046927SAndroid Build Coastguard Worker    clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, false);
785*61046927SAndroid Build Coastguard Worker }
786*61046927SAndroid Build Coastguard Worker 
787*61046927SAndroid Build Coastguard Worker 
788*61046927SAndroid Build Coastguard Worker /**
789*61046927SAndroid Build Coastguard Worker  * The ClearBuffer framework is so complicated and so riddled with the
790*61046927SAndroid Build Coastguard Worker  * assumption that the framebuffer is bound that, for now, we will just fake
791*61046927SAndroid Build Coastguard Worker  * direct state access clearing for the user.
792*61046927SAndroid Build Coastguard Worker  */
793*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedFramebufferfi(GLuint framebuffer,GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)794*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
795*61046927SAndroid Build Coastguard Worker                               GLint drawbuffer, GLfloat depth, GLint stencil)
796*61046927SAndroid Build Coastguard Worker {
797*61046927SAndroid Build Coastguard Worker    GLint oldfb;
798*61046927SAndroid Build Coastguard Worker 
799*61046927SAndroid Build Coastguard Worker    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
800*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
801*61046927SAndroid Build Coastguard Worker    _mesa_ClearBufferfi(buffer, drawbuffer, depth, stencil);
802*61046927SAndroid Build Coastguard Worker    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
803*61046927SAndroid Build Coastguard Worker }
804