blob: 0a51a868baef2aaf4f6f2567a592c3efe905e3ab [file] [log] [blame]
Brian Paul5ab1d0a2008-06-09 15:01:02 -06001/*
2 * Mesa 3-D graphics library
Brian Paul5ab1d0a2008-06-09 15:01:02 -06003 *
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Kenneth Graunke3d8d5b22013-04-21 13:46:48 -070019 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
Brian Paul5ab1d0a2008-06-09 15:01:02 -060023 */
24
25
26/**
27 * \file clear.c
28 * glClearColor, glClearIndex, glClear() functions.
29 */
30
31
32
Nanley Cheryd47cb412020-11-02 09:02:42 -080033#include "glformats.h"
Brian Paul5ab1d0a2008-06-09 15:01:02 -060034#include "glheader.h"
35#include "clear.h"
36#include "context.h"
Brian Paul2b5ece52009-12-30 09:25:24 -070037#include "enums.h"
Laura Ekstrand6236c472015-02-05 13:24:43 -080038#include "fbobject.h"
39#include "get.h"
Vinson Lee3fdd9fa2010-07-30 00:41:08 -070040#include "macros.h"
Vinson Lee0117da42011-01-05 23:11:54 -080041#include "mtypes.h"
Brian Paul5ab1d0a2008-06-09 15:01:02 -060042#include "state.h"
43
44
45
Brian Paul5ab1d0a2008-06-09 15:01:02 -060046void GLAPIENTRY
47_mesa_ClearIndex( GLfloat c )
48{
49 GET_CURRENT_CONTEXT(ctx);
Brian Paul5ab1d0a2008-06-09 15:01:02 -060050
Brian Paul5ab1d0a2008-06-09 15:01:02 -060051 ctx->Color.ClearIndex = (GLuint) c;
Brian Paul5ab1d0a2008-06-09 15:01:02 -060052}
Brian Paul5ab1d0a2008-06-09 15:01:02 -060053
54
55/**
56 * Specify the clear values for the color buffers.
57 *
58 * \param red red color component.
59 * \param green green color component.
60 * \param blue blue color component.
61 * \param alpha alpha component.
62 *
63 * \sa glClearColor().
Brian Paul5ab1d0a2008-06-09 15:01:02 -060064 */
65void GLAPIENTRY
66_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
67{
Brian Paul5ab1d0a2008-06-09 15:01:02 -060068 GET_CURRENT_CONTEXT(ctx);
Brian Paul5ab1d0a2008-06-09 15:01:02 -060069
Marek Olšák3140d132013-04-15 03:41:43 +020070 ctx->Color.ClearColor.f[0] = red;
71 ctx->Color.ClearColor.f[1] = green;
72 ctx->Color.ClearColor.f[2] = blue;
73 ctx->Color.ClearColor.f[3] = alpha;
Brian Paul5ab1d0a2008-06-09 15:01:02 -060074}
75
76
77/**
Brian Paula0bc8ee2010-10-23 09:26:10 -060078 * GL_EXT_texture_integer
79 */
80void GLAPIENTRY
81_mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
82{
Brian Paula0bc8ee2010-10-23 09:26:10 -060083 GET_CURRENT_CONTEXT(ctx);
Brian Paula0bc8ee2010-10-23 09:26:10 -060084
Marek Olšák3140d132013-04-15 03:41:43 +020085 ctx->Color.ClearColor.i[0] = r;
86 ctx->Color.ClearColor.i[1] = g;
87 ctx->Color.ClearColor.i[2] = b;
88 ctx->Color.ClearColor.i[3] = a;
Brian Paula0bc8ee2010-10-23 09:26:10 -060089}
90
91
92/**
93 * GL_EXT_texture_integer
94 */
95void GLAPIENTRY
96_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
97{
Brian Paula0bc8ee2010-10-23 09:26:10 -060098 GET_CURRENT_CONTEXT(ctx);
Brian Paula0bc8ee2010-10-23 09:26:10 -060099
Marek Olšák3140d132013-04-15 03:41:43 +0200100 ctx->Color.ClearColor.ui[0] = r;
101 ctx->Color.ClearColor.ui[1] = g;
102 ctx->Color.ClearColor.ui[2] = b;
103 ctx->Color.ClearColor.ui[3] = a;
Brian Paula0bc8ee2010-10-23 09:26:10 -0600104}
105
106
107/**
Kenneth Graunke630bf282014-03-21 15:58:02 -0700108 * Returns true if color writes are enabled for the given color attachment.
109 *
110 * Beyond checking ColorMask, this uses _mesa_format_has_color_component to
111 * ignore components that don't actually exist in the format (such as X in
112 * XRGB).
113 */
114static bool
115color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx)
116{
117 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx];
118 GLuint c;
Kenneth Graunke630bf282014-03-21 15:58:02 -0700119
120 if (rb) {
121 for (c = 0; c < 4; c++) {
Marek Olšákaf3685d2018-01-31 03:03:25 +0100122 if (GET_COLORMASK_BIT(ctx->Color.ColorMask, idx, c) &&
Brian Paul6b601532017-04-27 08:52:30 -0600123 _mesa_format_has_color_component(rb->Format, c)) {
124 return true;
125 }
Kenneth Graunke630bf282014-03-21 15:58:02 -0700126 }
127 }
128
Brian Paul6b601532017-04-27 08:52:30 -0600129 return false;
Kenneth Graunke630bf282014-03-21 15:58:02 -0700130}
131
132
133/**
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600134 * Clear buffers.
Brian Paule725dc02014-12-12 16:45:33 -0700135 *
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600136 * \param mask bit-mask indicating the buffers to be cleared.
137 *
Brian Paule725dc02014-12-12 16:45:33 -0700138 * Flushes the vertices and verifies the parameter.
Jakob Bornecrantz09171702018-09-19 15:21:26 +0100139 * If __struct gl_contextRec::NewState is set then calls _mesa_update_state()
140 * to update gl_frame_buffer::_Xmin, etc. If the rasterization mode is set to
141 * GL_RENDER then requests the driver to clear the buffers, via the
142 * dd_function_table::Clear callback.
Brian Paule725dc02014-12-12 16:45:33 -0700143 */
Samuel Pitoiset34e8d0e2017-06-26 17:44:44 +0200144static ALWAYS_INLINE void
145clear(struct gl_context *ctx, GLbitfield mask, bool no_error)
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600146{
Eric Anholta9754792013-01-16 16:20:38 -0800147 FLUSH_VERTICES(ctx, 0);
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600148
Samuel Pitoiset34e8d0e2017-06-26 17:44:44 +0200149 if (!no_error) {
150 if (mask & ~(GL_COLOR_BUFFER_BIT |
151 GL_DEPTH_BUFFER_BIT |
152 GL_STENCIL_BUFFER_BIT |
153 GL_ACCUM_BUFFER_BIT)) {
154 _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
155 return;
156 }
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600157
Samuel Pitoiset34e8d0e2017-06-26 17:44:44 +0200158 /* Accumulation buffers were removed in core contexts, and they never
159 * existed in OpenGL ES.
160 */
161 if ((mask & GL_ACCUM_BUFFER_BIT) != 0
162 && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) {
163 _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
164 return;
165 }
Ian Romanicke58c19a2011-09-20 16:39:30 -0700166 }
167
Jakob Bornecrantz09171702018-09-19 15:21:26 +0100168 if (ctx->NewState) {
169 _mesa_update_state( ctx ); /* update _Xmin, etc */
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600170 }
171
Samuel Pitoiset34e8d0e2017-06-26 17:44:44 +0200172 if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600173 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
174 "glClear(incomplete framebuffer)");
175 return;
176 }
177
Paul Berryaee96802011-12-20 16:18:39 -0800178 if (ctx->RasterDiscard)
Eric Anholte7c2b712011-09-29 23:13:44 -0700179 return;
180
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600181 if (ctx->RenderMode == GL_RENDER) {
182 GLbitfield bufferMask;
183
184 /* don't clear depth buffer if depth writing disabled */
185 if (!ctx->Depth.Mask)
186 mask &= ~GL_DEPTH_BUFFER_BIT;
187
188 /* Build the bitmask to send to device driver's Clear function.
189 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
190 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
191 * BUFFER_BIT_COLORn flags.
192 */
193 bufferMask = 0;
194 if (mask & GL_COLOR_BUFFER_BIT) {
195 GLuint i;
196 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
Brian Paulf8bae522017-11-08 22:18:40 -0700197 gl_buffer_index buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
Marek Olšák9bf95782014-01-08 01:23:43 +0100198
Brian Paulf8bae522017-11-08 22:18:40 -0700199 if (buf != BUFFER_NONE && color_buffer_writes_enabled(ctx, i)) {
Marek Olšák9bf95782014-01-08 01:23:43 +0100200 bufferMask |= 1 << buf;
201 }
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600202 }
203 }
204
205 if ((mask & GL_DEPTH_BUFFER_BIT)
Adam Jackson78e0fa62019-09-06 11:51:23 -0400206 && ctx->DrawBuffer->Visual.depthBits > 0) {
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600207 bufferMask |= BUFFER_BIT_DEPTH;
208 }
209
210 if ((mask & GL_STENCIL_BUFFER_BIT)
Adam Jackson78e0fa62019-09-06 11:51:23 -0400211 && ctx->DrawBuffer->Visual.stencilBits > 0) {
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600212 bufferMask |= BUFFER_BIT_STENCIL;
213 }
214
215 if ((mask & GL_ACCUM_BUFFER_BIT)
Adam Jackson78e0fa62019-09-06 11:51:23 -0400216 && ctx->DrawBuffer->Visual.accumRedBits > 0) {
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600217 bufferMask |= BUFFER_BIT_ACCUM;
218 }
219
Matt Turnerbfcdb842015-02-20 20:18:47 -0800220 assert(ctx->Driver.Clear);
Brian Paul5ab1d0a2008-06-09 15:01:02 -0600221 ctx->Driver.Clear(ctx, bufferMask);
222 }
223}
Brian Paul2b5ece52009-12-30 09:25:24 -0700224
225
Samuel Pitoiset34e8d0e2017-06-26 17:44:44 +0200226void GLAPIENTRY
Samuel Pitoisete529ade2017-06-26 17:46:39 +0200227_mesa_Clear_no_error(GLbitfield mask)
228{
229 GET_CURRENT_CONTEXT(ctx);
230 clear(ctx, mask, true);
231}
232
233
234void GLAPIENTRY
Samuel Pitoiset34e8d0e2017-06-26 17:44:44 +0200235_mesa_Clear(GLbitfield mask)
236{
237 GET_CURRENT_CONTEXT(ctx);
238
239 if (MESA_VERBOSE & VERBOSE_API)
240 _mesa_debug(ctx, "glClear 0x%x\n", mask);
241
242 clear(ctx, mask, false);
243}
244
245
Brian Paul2b5ece52009-12-30 09:25:24 -0700246/** Returned by make_color_buffer_mask() for errors */
Jan Vesely3cb10cc2015-01-15 13:41:04 -0500247#define INVALID_MASK ~0x0U
Brian Paul2b5ece52009-12-30 09:25:24 -0700248
249
250/**
251 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
252 * BUFFER_BIT_x values.
253 * Return INVALID_MASK if the drawbuffer value is invalid.
254 */
255static GLbitfield
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400256make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
Brian Paul2b5ece52009-12-30 09:25:24 -0700257{
258 const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
259 GLbitfield mask = 0x0;
260
Marek Olšák03d848e2013-12-04 00:27:20 +0100261 /* From the GL 4.0 specification:
262 * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
263 * specified by passing i as the parameter drawbuffer, and value
264 * points to a four-element vector specifying the R, G, B, and A
265 * color to clear that draw buffer to. If the draw buffer is one
266 * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
267 * multiple buffers, each selected buffer is cleared to the same
268 * value.
269 *
270 * Note that "drawbuffer" and "draw buffer" have different meaning.
271 * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
272 * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
273 * etc.
274 */
275 if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
276 return INVALID_MASK;
277 }
278
279 switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700280 case GL_FRONT:
281 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
282 mask |= BUFFER_BIT_FRONT_LEFT;
283 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
284 mask |= BUFFER_BIT_FRONT_RIGHT;
285 break;
286 case GL_BACK:
Gurchetan Singh2e6d3582016-06-30 15:20:34 -0700287 /* For GLES contexts with a single buffered configuration, we actually
288 * only have a front renderbuffer, so any clear calls to GL_BACK should
289 * affect that buffer. See draw_buffer_enum_to_bitmask for details.
290 */
291 if (_mesa_is_gles(ctx))
292 if (!ctx->DrawBuffer->Visual.doubleBufferMode)
293 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
294 mask |= BUFFER_BIT_FRONT_LEFT;
Brian Paul2b5ece52009-12-30 09:25:24 -0700295 if (att[BUFFER_BACK_LEFT].Renderbuffer)
296 mask |= BUFFER_BIT_BACK_LEFT;
297 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
298 mask |= BUFFER_BIT_BACK_RIGHT;
299 break;
300 case GL_LEFT:
301 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
302 mask |= BUFFER_BIT_FRONT_LEFT;
303 if (att[BUFFER_BACK_LEFT].Renderbuffer)
304 mask |= BUFFER_BIT_BACK_LEFT;
305 break;
306 case GL_RIGHT:
307 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
308 mask |= BUFFER_BIT_FRONT_RIGHT;
309 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
310 mask |= BUFFER_BIT_BACK_RIGHT;
311 break;
312 case GL_FRONT_AND_BACK:
313 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
314 mask |= BUFFER_BIT_FRONT_LEFT;
315 if (att[BUFFER_BACK_LEFT].Renderbuffer)
316 mask |= BUFFER_BIT_BACK_LEFT;
317 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
318 mask |= BUFFER_BIT_FRONT_RIGHT;
319 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
320 mask |= BUFFER_BIT_BACK_RIGHT;
321 break;
322 default:
Marek Olšák03d848e2013-12-04 00:27:20 +0100323 {
Brian Paulf8bae522017-11-08 22:18:40 -0700324 gl_buffer_index buf =
325 ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
Marek Olšák03d848e2013-12-04 00:27:20 +0100326
Brian Paulf8bae522017-11-08 22:18:40 -0700327 if (buf != BUFFER_NONE && att[buf].Renderbuffer) {
Marek Olšák03d848e2013-12-04 00:27:20 +0100328 mask |= 1 << buf;
329 }
Brian Paul2b5ece52009-12-30 09:25:24 -0700330 }
331 }
332
333 return mask;
334}
335
336
337
338/**
339 * New in GL 3.0
340 * Clear signed integer color buffer or stencil buffer (not depth).
341 */
Samuel Pitoiset54bd9a12017-07-21 14:27:23 +0200342static ALWAYS_INLINE void
343clear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
344 const GLint *value, bool no_error)
Brian Paul2b5ece52009-12-30 09:25:24 -0700345{
Eric Anholta9754792013-01-16 16:20:38 -0800346 FLUSH_VERTICES(ctx, 0);
Brian Paul2b5ece52009-12-30 09:25:24 -0700347
Jakob Bornecrantz09171702018-09-19 15:21:26 +0100348 if (ctx->NewState) {
349 _mesa_update_state( ctx );
Brian Paul2b5ece52009-12-30 09:25:24 -0700350 }
351
Lionel Landwerlin88d66582019-11-01 19:43:00 +0200352 if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
353 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
354 "glClearBufferiv(incomplete framebuffer)");
355 return;
356 }
357
Brian Paul2b5ece52009-12-30 09:25:24 -0700358 switch (buffer) {
359 case GL_STENCIL:
Ian Romanick295e07e2011-11-01 15:11:12 -0700360 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
361 *
362 * "ClearBuffer generates an INVALID VALUE error if buffer is
363 * COLOR and drawbuffer is less than zero, or greater than the
364 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
365 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
366 */
Samuel Pitoiset54bd9a12017-07-21 14:27:23 +0200367 if (!no_error && drawbuffer != 0) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700368 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
369 drawbuffer);
370 return;
371 }
Brian Paule725dc02014-12-12 16:45:33 -0700372 else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer
373 && !ctx->RasterDiscard) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700374 /* Save current stencil clear value, set to 'value', do the
375 * stencil clear and restore the clear value.
376 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
377 * hook instead.
378 */
379 const GLuint clearSave = ctx->Stencil.Clear;
380 ctx->Stencil.Clear = *value;
Brian Paul2b5ece52009-12-30 09:25:24 -0700381 ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
382 ctx->Stencil.Clear = clearSave;
Brian Paul2b5ece52009-12-30 09:25:24 -0700383 }
384 break;
385 case GL_COLOR:
386 {
387 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
Samuel Pitoiset54bd9a12017-07-21 14:27:23 +0200388 if (!no_error && mask == INVALID_MASK) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700389 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
390 drawbuffer);
391 return;
392 }
Paul Berryaee96802011-12-20 16:18:39 -0800393 else if (mask && !ctx->RasterDiscard) {
Dave Airlie093dc9e2011-09-12 10:57:40 +0100394 union gl_color_union clearSave;
395
Brian Paul2b5ece52009-12-30 09:25:24 -0700396 /* save color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100397 clearSave = ctx->Color.ClearColor;
Brian Paul2b5ece52009-12-30 09:25:24 -0700398 /* set color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100399 COPY_4V(ctx->Color.ClearColor.i, value);
Brian Paul2b5ece52009-12-30 09:25:24 -0700400 /* clear buffer(s) */
401 ctx->Driver.Clear(ctx, mask);
402 /* restore color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100403 ctx->Color.ClearColor = clearSave;
Brian Paul2b5ece52009-12-30 09:25:24 -0700404 }
405 }
406 break;
407 default:
Samuel Pitoiset54bd9a12017-07-21 14:27:23 +0200408 if (!no_error) {
409 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
410 * of the OpenGL 4.5 spec states:
411 *
412 * "An INVALID_ENUM error is generated by ClearBufferiv and
413 * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
414 */
415 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
416 _mesa_enum_to_string(buffer));
417 }
Brian Paul2b5ece52009-12-30 09:25:24 -0700418 return;
419 }
420}
421
422
Samuel Pitoiset54bd9a12017-07-21 14:27:23 +0200423void GLAPIENTRY
Samuel Pitoisetda0ecda2017-07-21 14:28:52 +0200424_mesa_ClearBufferiv_no_error(GLenum buffer, GLint drawbuffer, const GLint *value)
425{
426 GET_CURRENT_CONTEXT(ctx);
427 clear_bufferiv(ctx, buffer, drawbuffer, value, true);
428}
429
430
431void GLAPIENTRY
Samuel Pitoiset54bd9a12017-07-21 14:27:23 +0200432_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
433{
434 GET_CURRENT_CONTEXT(ctx);
435 clear_bufferiv(ctx, buffer, drawbuffer, value, false);
436}
437
438
Brian Paul2b5ece52009-12-30 09:25:24 -0700439/**
Laura Ekstrand6236c472015-02-05 13:24:43 -0800440 * The ClearBuffer framework is so complicated and so riddled with the
441 * assumption that the framebuffer is bound that, for now, we will just fake
442 * direct state access clearing for the user.
443 */
444void GLAPIENTRY
445_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
446 GLint drawbuffer, const GLint *value)
447{
448 GLint oldfb;
449
450 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
451 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
452 _mesa_ClearBufferiv(buffer, drawbuffer, value);
453 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
454}
455
456
457/**
Brian Paul2b5ece52009-12-30 09:25:24 -0700458 * New in GL 3.0
459 * Clear unsigned integer color buffer (not depth, not stencil).
460 */
Samuel Pitoisetb18b1fa2017-07-21 14:23:35 +0200461static ALWAYS_INLINE void
462clear_bufferuiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
463 const GLuint *value, bool no_error)
Brian Paul2b5ece52009-12-30 09:25:24 -0700464{
Eric Anholta9754792013-01-16 16:20:38 -0800465 FLUSH_VERTICES(ctx, 0);
Brian Paul2b5ece52009-12-30 09:25:24 -0700466
Jakob Bornecrantz09171702018-09-19 15:21:26 +0100467 if (ctx->NewState) {
468 _mesa_update_state( ctx );
Brian Paul2b5ece52009-12-30 09:25:24 -0700469 }
470
Dmitriy Nester58bb8172020-04-30 16:25:04 +0300471 if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
472 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
473 "glClearBufferuiv(incomplete framebuffer)");
474 return;
475 }
476
Brian Paul2b5ece52009-12-30 09:25:24 -0700477 switch (buffer) {
478 case GL_COLOR:
479 {
480 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
Samuel Pitoisetb18b1fa2017-07-21 14:23:35 +0200481 if (!no_error && mask == INVALID_MASK) {
Brian Paul197b1d72010-11-19 14:34:07 -0700482 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
Brian Paul2b5ece52009-12-30 09:25:24 -0700483 drawbuffer);
484 return;
485 }
Paul Berryaee96802011-12-20 16:18:39 -0800486 else if (mask && !ctx->RasterDiscard) {
Dave Airlie093dc9e2011-09-12 10:57:40 +0100487 union gl_color_union clearSave;
488
Brian Paul2b5ece52009-12-30 09:25:24 -0700489 /* save color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100490 clearSave = ctx->Color.ClearColor;
Brian Paul2b5ece52009-12-30 09:25:24 -0700491 /* set color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100492 COPY_4V(ctx->Color.ClearColor.ui, value);
Brian Paul2b5ece52009-12-30 09:25:24 -0700493 /* clear buffer(s) */
494 ctx->Driver.Clear(ctx, mask);
495 /* restore color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100496 ctx->Color.ClearColor = clearSave;
Brian Paul2b5ece52009-12-30 09:25:24 -0700497 }
498 }
499 break;
500 default:
Samuel Pitoisetb18b1fa2017-07-21 14:23:35 +0200501 if (!no_error) {
502 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
503 * of the OpenGL 4.5 spec states:
504 *
505 * "An INVALID_ENUM error is generated by ClearBufferuiv and
506 * ClearNamedFramebufferuiv if buffer is not COLOR."
507 */
508 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
509 _mesa_enum_to_string(buffer));
510 }
Brian Paul2b5ece52009-12-30 09:25:24 -0700511 return;
512 }
513}
514
515
Samuel Pitoisetb18b1fa2017-07-21 14:23:35 +0200516void GLAPIENTRY
Samuel Pitoiset11e05422017-07-21 14:25:03 +0200517_mesa_ClearBufferuiv_no_error(GLenum buffer, GLint drawbuffer,
518 const GLuint *value)
519{
520 GET_CURRENT_CONTEXT(ctx);
521 clear_bufferuiv(ctx, buffer, drawbuffer, value, true);
522}
523
524
525void GLAPIENTRY
Samuel Pitoisetb18b1fa2017-07-21 14:23:35 +0200526_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
527{
528 GET_CURRENT_CONTEXT(ctx);
529 clear_bufferuiv(ctx, buffer, drawbuffer, value, false);
530}
531
532
Brian Paul2b5ece52009-12-30 09:25:24 -0700533/**
Laura Ekstrand43db4b82015-02-05 13:30:50 -0800534 * The ClearBuffer framework is so complicated and so riddled with the
535 * assumption that the framebuffer is bound that, for now, we will just fake
536 * direct state access clearing for the user.
537 */
538void GLAPIENTRY
539_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
540 GLint drawbuffer, const GLuint *value)
541{
542 GLint oldfb;
543
544 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
545 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
546 _mesa_ClearBufferuiv(buffer, drawbuffer, value);
547 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
548}
549
550
551/**
Brian Paul2b5ece52009-12-30 09:25:24 -0700552 * New in GL 3.0
553 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
554 */
Samuel Pitoiset33b47302017-07-21 14:02:20 +0200555static ALWAYS_INLINE void
556clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
557 const GLfloat *value, bool no_error)
Brian Paul2b5ece52009-12-30 09:25:24 -0700558{
Eric Anholta9754792013-01-16 16:20:38 -0800559 FLUSH_VERTICES(ctx, 0);
Brian Paul2b5ece52009-12-30 09:25:24 -0700560
Jakob Bornecrantz09171702018-09-19 15:21:26 +0100561 if (ctx->NewState) {
562 _mesa_update_state( ctx );
Brian Paul2b5ece52009-12-30 09:25:24 -0700563 }
564
Dmitriy Nester58bb8172020-04-30 16:25:04 +0300565 if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
566 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
567 "glClearBufferfv(incomplete framebuffer)");
568 return;
569 }
570
Brian Paul2b5ece52009-12-30 09:25:24 -0700571 switch (buffer) {
572 case GL_DEPTH:
Ian Romanick295e07e2011-11-01 15:11:12 -0700573 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
574 *
575 * "ClearBuffer generates an INVALID VALUE error if buffer is
576 * COLOR and drawbuffer is less than zero, or greater than the
577 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
578 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
579 */
Samuel Pitoiset33b47302017-07-21 14:02:20 +0200580 if (!no_error && drawbuffer != 0) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700581 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
582 drawbuffer);
583 return;
584 }
Brian Paule725dc02014-12-12 16:45:33 -0700585 else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer
586 && !ctx->RasterDiscard) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700587 /* Save current depth clear value, set to 'value', do the
588 * depth clear and restore the clear value.
589 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
590 * hook instead.
591 */
Karl Schultzb30898f2010-02-13 17:31:58 -0700592 const GLclampd clearSave = ctx->Depth.Clear;
Nanley Cheryd47cb412020-11-02 09:02:42 -0800593
594 /* Page 263 (page 279 of the PDF) of the OpenGL 3.0 spec says:
595 *
596 * "If buffer is DEPTH, drawbuffer must be zero, and value points
597 * to the single depth value to clear the depth buffer to.
598 * Clamping and type conversion for fixed-point depth buffers are
599 * performed in the same fashion as for ClearDepth."
600 */
601 const struct gl_renderbuffer *rb =
602 ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
603 const bool is_float_depth =
604 _mesa_has_depth_float_channel(rb->InternalFormat);
605 ctx->Depth.Clear = is_float_depth ? *value : SATURATE(*value);
606
Brian Paul2b5ece52009-12-30 09:25:24 -0700607 ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
608 ctx->Depth.Clear = clearSave;
Brian Paul2b5ece52009-12-30 09:25:24 -0700609 }
610 /* clear depth buffer to value */
611 break;
612 case GL_COLOR:
613 {
614 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
Samuel Pitoiset33b47302017-07-21 14:02:20 +0200615 if (!no_error && mask == INVALID_MASK) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700616 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
617 drawbuffer);
618 return;
619 }
Paul Berryaee96802011-12-20 16:18:39 -0800620 else if (mask && !ctx->RasterDiscard) {
Dave Airlie093dc9e2011-09-12 10:57:40 +0100621 union gl_color_union clearSave;
622
Brian Paul2b5ece52009-12-30 09:25:24 -0700623 /* save color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100624 clearSave = ctx->Color.ClearColor;
Brian Paul2b5ece52009-12-30 09:25:24 -0700625 /* set color */
Brian Paulcf41d7c2012-08-25 06:43:37 -0600626 COPY_4V(ctx->Color.ClearColor.f, value);
Brian Paul2b5ece52009-12-30 09:25:24 -0700627 /* clear buffer(s) */
628 ctx->Driver.Clear(ctx, mask);
629 /* restore color */
Dave Airlie093dc9e2011-09-12 10:57:40 +0100630 ctx->Color.ClearColor = clearSave;
Brian Paul2b5ece52009-12-30 09:25:24 -0700631 }
632 }
633 break;
634 default:
Samuel Pitoiset33b47302017-07-21 14:02:20 +0200635 if (!no_error) {
636 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
637 * of the OpenGL 4.5 spec states:
638 *
639 * "An INVALID_ENUM error is generated by ClearBufferfv and
640 * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
641 */
642 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
643 _mesa_enum_to_string(buffer));
644 }
Brian Paul2b5ece52009-12-30 09:25:24 -0700645 return;
646 }
647}
648
649
Samuel Pitoiset33b47302017-07-21 14:02:20 +0200650void GLAPIENTRY
Samuel Pitoiset5e05e7d2017-07-21 14:04:15 +0200651_mesa_ClearBufferfv_no_error(GLenum buffer, GLint drawbuffer,
652 const GLfloat *value)
653{
654 GET_CURRENT_CONTEXT(ctx);
655 clear_bufferfv(ctx, buffer, drawbuffer, value, true);
656}
657
658
659void GLAPIENTRY
Samuel Pitoiset33b47302017-07-21 14:02:20 +0200660_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
661{
662 GET_CURRENT_CONTEXT(ctx);
663 clear_bufferfv(ctx, buffer, drawbuffer, value, false);
664}
665
666
Brian Paul2b5ece52009-12-30 09:25:24 -0700667/**
Laura Ekstrandbbd9c552015-02-05 13:38:39 -0800668 * The ClearBuffer framework is so complicated and so riddled with the
669 * assumption that the framebuffer is bound that, for now, we will just fake
670 * direct state access clearing for the user.
671 */
672void GLAPIENTRY
673_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
674 GLint drawbuffer, const GLfloat *value)
675{
676 GLint oldfb;
677
678 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
679 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
680 _mesa_ClearBufferfv(buffer, drawbuffer, value);
681 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
682}
683
684
685/**
Brian Paul2b5ece52009-12-30 09:25:24 -0700686 * New in GL 3.0
687 * Clear depth/stencil buffer only.
688 */
Samuel Pitoiset1ed61e02017-07-21 14:19:27 +0200689static ALWAYS_INLINE void
690clear_bufferfi(struct gl_context *ctx, GLenum buffer, GLint drawbuffer,
691 GLfloat depth, GLint stencil, bool no_error)
Brian Paul2b5ece52009-12-30 09:25:24 -0700692{
Dave Airlie092cf9a2012-01-10 12:48:26 +0000693 GLbitfield mask = 0;
694
Eric Anholta9754792013-01-16 16:20:38 -0800695 FLUSH_VERTICES(ctx, 0);
Brian Paul2b5ece52009-12-30 09:25:24 -0700696
Samuel Pitoiset1ed61e02017-07-21 14:19:27 +0200697 if (!no_error) {
698 if (buffer != GL_DEPTH_STENCIL) {
699 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
700 _mesa_enum_to_string(buffer));
701 return;
702 }
Brian Paul2b5ece52009-12-30 09:25:24 -0700703
Samuel Pitoiset1ed61e02017-07-21 14:19:27 +0200704 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
705 *
706 * "ClearBuffer generates an INVALID VALUE error if buffer is
707 * COLOR and drawbuffer is less than zero, or greater than the
708 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
709 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
710 */
711 if (drawbuffer != 0) {
712 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
713 drawbuffer);
714 return;
715 }
Brian Paul2b5ece52009-12-30 09:25:24 -0700716 }
717
Paul Berryaee96802011-12-20 16:18:39 -0800718 if (ctx->RasterDiscard)
Eric Anholte7c2b712011-09-29 23:13:44 -0700719 return;
720
Jakob Bornecrantz09171702018-09-19 15:21:26 +0100721 if (ctx->NewState) {
722 _mesa_update_state( ctx );
Brian Paul2b5ece52009-12-30 09:25:24 -0700723 }
724
Lionel Landwerlinf93bb902019-11-11 12:32:50 +0200725 if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
726 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
727 "glClearBufferfi(incomplete framebuffer)");
728 return;
729 }
730
Dave Airlie092cf9a2012-01-10 12:48:26 +0000731 if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
732 mask |= BUFFER_BIT_DEPTH;
733 if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
734 mask |= BUFFER_BIT_STENCIL;
735
736 if (mask) {
Brian Paul2b5ece52009-12-30 09:25:24 -0700737 /* save current clear values */
Karl Schultzb30898f2010-02-13 17:31:58 -0700738 const GLclampd clearDepthSave = ctx->Depth.Clear;
Brian Paul2b5ece52009-12-30 09:25:24 -0700739 const GLuint clearStencilSave = ctx->Stencil.Clear;
740
741 /* set new clear values */
742 ctx->Depth.Clear = depth;
743 ctx->Stencil.Clear = stencil;
Brian Paul2b5ece52009-12-30 09:25:24 -0700744
745 /* clear buffers */
Dave Airlie092cf9a2012-01-10 12:48:26 +0000746 ctx->Driver.Clear(ctx, mask);
Brian Paul2b5ece52009-12-30 09:25:24 -0700747
748 /* restore */
749 ctx->Depth.Clear = clearDepthSave;
750 ctx->Stencil.Clear = clearStencilSave;
Brian Paul2b5ece52009-12-30 09:25:24 -0700751 }
752}
Laura Ekstranda0329c72015-02-05 13:43:12 -0800753
754
Samuel Pitoiset1ed61e02017-07-21 14:19:27 +0200755void GLAPIENTRY
Samuel Pitoiset73c5e752017-07-21 14:21:10 +0200756_mesa_ClearBufferfi_no_error(GLenum buffer, GLint drawbuffer,
757 GLfloat depth, GLint stencil)
758{
759 GET_CURRENT_CONTEXT(ctx);
760 clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, true);
761}
762
763
764void GLAPIENTRY
Samuel Pitoiset1ed61e02017-07-21 14:19:27 +0200765_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
766 GLfloat depth, GLint stencil)
767{
768 GET_CURRENT_CONTEXT(ctx);
769 clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, false);
770}
771
772
Laura Ekstranda0329c72015-02-05 13:43:12 -0800773/**
774 * The ClearBuffer framework is so complicated and so riddled with the
775 * assumption that the framebuffer is bound that, for now, we will just fake
776 * direct state access clearing for the user.
777 */
778void GLAPIENTRY
779_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
Ilia Mirkin7d7e0152016-06-09 23:45:22 -0400780 GLint drawbuffer, GLfloat depth, GLint stencil)
Laura Ekstranda0329c72015-02-05 13:43:12 -0800781{
782 GLint oldfb;
783
784 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
785 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
Ilia Mirkin7d7e0152016-06-09 23:45:22 -0400786 _mesa_ClearBufferfi(buffer, drawbuffer, depth, stencil);
Laura Ekstranda0329c72015-02-05 13:43:12 -0800787 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
788}