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