X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fclear.c;h=6beff9ed842bc7e38a8cd93429c92298b8184c1f;hb=9d670fd86cc13df0ddff5c6fcb0835926e9a8088;hp=a1bb36efe241e0508b6fd09dd917f43501713082;hpb=2e6d35809bf4ef60af62f9c84d394e97d5bbe2a7;p=mesa.git diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c index a1bb36efe24..6beff9ed842 100644 --- a/src/mesa/main/clear.c +++ b/src/mesa/main/clear.c @@ -115,16 +115,17 @@ color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx) { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx]; GLuint c; - GLubyte colorMask = 0; if (rb) { for (c = 0; c < 4; c++) { - if (_mesa_format_has_color_component(rb->Format, c)) - colorMask |= ctx->Color.ColorMask[idx][c]; + if (GET_COLORMASK_BIT(ctx->Color.ColorMask, idx, c) && + _mesa_format_has_color_component(rb->Format, c)) { + return true; + } } } - return colorMask != 0; + return false; } @@ -139,40 +140,36 @@ color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx) * GL_RENDER then requests the driver to clear the buffers, via the * dd_function_table::Clear callback. */ -void GLAPIENTRY -_mesa_Clear( GLbitfield mask ) +static ALWAYS_INLINE void +clear(struct gl_context *ctx, GLbitfield mask, bool no_error) { - GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); - FLUSH_CURRENT(ctx, 0); - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glClear 0x%x\n", mask); - - if (mask & ~(GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_STENCIL_BUFFER_BIT | - GL_ACCUM_BUFFER_BIT)) { - /* invalid bit set */ - _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); - return; - } + if (!no_error) { + if (mask & ~(GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT | + GL_STENCIL_BUFFER_BIT | + GL_ACCUM_BUFFER_BIT)) { + _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); + return; + } - /* Accumulation buffers were removed in core contexts, and they never - * existed in OpenGL ES. - */ - if ((mask & GL_ACCUM_BUFFER_BIT) != 0 - && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) { - _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)"); - return; + /* Accumulation buffers were removed in core contexts, and they never + * existed in OpenGL ES. + */ + if ((mask & GL_ACCUM_BUFFER_BIT) != 0 + && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) { + _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)"); + return; + } } if (ctx->NewState) { _mesa_update_state( ctx ); /* update _Xmin, etc */ } - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glClear(incomplete framebuffer)"); return; @@ -197,9 +194,9 @@ _mesa_Clear( GLbitfield mask ) if (mask & GL_COLOR_BUFFER_BIT) { GLuint i; for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; + gl_buffer_index buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; - if (buf >= 0 && color_buffer_writes_enabled(ctx, i)) { + if (buf != BUFFER_NONE && color_buffer_writes_enabled(ctx, i)) { bufferMask |= 1 << buf; } } @@ -226,6 +223,26 @@ _mesa_Clear( GLbitfield mask ) } +void GLAPIENTRY +_mesa_Clear_no_error(GLbitfield mask) +{ + GET_CURRENT_CONTEXT(ctx); + clear(ctx, mask, true); +} + + +void GLAPIENTRY +_mesa_Clear(GLbitfield mask) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glClear 0x%x\n", mask); + + clear(ctx, mask, false); +} + + /** Returned by make_color_buffer_mask() for errors */ #define INVALID_MASK ~0x0U @@ -304,9 +321,10 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) break; default: { - GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; + gl_buffer_index buf = + ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; - if (buf >= 0 && att[buf].Renderbuffer) { + if (buf != BUFFER_NONE && att[buf].Renderbuffer) { mask |= 1 << buf; } } @@ -321,12 +339,11 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) * New in GL 3.0 * Clear signed integer color buffer or stencil buffer (not depth). */ -void GLAPIENTRY -_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) +static ALWAYS_INLINE void +clear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, + const GLint *value, bool no_error) { - GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); - FLUSH_CURRENT(ctx, 0); if (ctx->NewState) { @@ -342,7 +359,7 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." */ - if (drawbuffer != 0) { + if (!no_error && drawbuffer != 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", drawbuffer); return; @@ -363,7 +380,7 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) case GL_COLOR: { const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); - if (mask == INVALID_MASK) { + if (!no_error && mask == INVALID_MASK) { _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", drawbuffer); return; @@ -383,19 +400,37 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) } break; default: - /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' - * of the OpenGL 4.5 spec states: - * - * "An INVALID_ENUM error is generated by ClearBufferiv and - * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL." - */ - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", - _mesa_enum_to_string(buffer)); + if (!no_error) { + /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' + * of the OpenGL 4.5 spec states: + * + * "An INVALID_ENUM error is generated by ClearBufferiv and + * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL." + */ + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", + _mesa_enum_to_string(buffer)); + } return; } } +void GLAPIENTRY +_mesa_ClearBufferiv_no_error(GLenum buffer, GLint drawbuffer, const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferiv(ctx, buffer, drawbuffer, value, true); +} + + +void GLAPIENTRY +_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferiv(ctx, buffer, drawbuffer, value, false); +} + + /** * The ClearBuffer framework is so complicated and so riddled with the * assumption that the framebuffer is bound that, for now, we will just fake @@ -418,11 +453,10 @@ _mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, * New in GL 3.0 * Clear unsigned integer color buffer (not depth, not stencil). */ -void GLAPIENTRY -_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) +static ALWAYS_INLINE void +clear_bufferuiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, + const GLuint *value, bool no_error) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); FLUSH_CURRENT(ctx, 0); @@ -434,7 +468,7 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) case GL_COLOR: { const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); - if (mask == INVALID_MASK) { + if (!no_error && mask == INVALID_MASK) { _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", drawbuffer); return; @@ -454,19 +488,38 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) } break; default: - /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' - * of the OpenGL 4.5 spec states: - * - * "An INVALID_ENUM error is generated by ClearBufferuiv and - * ClearNamedFramebufferuiv if buffer is not COLOR." - */ - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", - _mesa_enum_to_string(buffer)); + if (!no_error) { + /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' + * of the OpenGL 4.5 spec states: + * + * "An INVALID_ENUM error is generated by ClearBufferuiv and + * ClearNamedFramebufferuiv if buffer is not COLOR." + */ + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", + _mesa_enum_to_string(buffer)); + } return; } } +void GLAPIENTRY +_mesa_ClearBufferuiv_no_error(GLenum buffer, GLint drawbuffer, + const GLuint *value) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferuiv(ctx, buffer, drawbuffer, value, true); +} + + +void GLAPIENTRY +_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferuiv(ctx, buffer, drawbuffer, value, false); +} + + /** * The ClearBuffer framework is so complicated and so riddled with the * assumption that the framebuffer is bound that, for now, we will just fake @@ -489,11 +542,10 @@ _mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, * New in GL 3.0 * Clear fixed-pt or float color buffer or depth buffer (not stencil). */ -void GLAPIENTRY -_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) +static ALWAYS_INLINE void +clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, + const GLfloat *value, bool no_error) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); FLUSH_CURRENT(ctx, 0); @@ -510,7 +562,7 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." */ - if (drawbuffer != 0) { + if (!no_error && drawbuffer != 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", drawbuffer); return; @@ -532,7 +584,7 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) case GL_COLOR: { const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); - if (mask == INVALID_MASK) { + if (!no_error && mask == INVALID_MASK) { _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", drawbuffer); return; @@ -552,19 +604,38 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) } break; default: - /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' - * of the OpenGL 4.5 spec states: - * - * "An INVALID_ENUM error is generated by ClearBufferfv and - * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH." - */ - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", - _mesa_enum_to_string(buffer)); + if (!no_error) { + /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' + * of the OpenGL 4.5 spec states: + * + * "An INVALID_ENUM error is generated by ClearBufferfv and + * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH." + */ + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", + _mesa_enum_to_string(buffer)); + } return; } } +void GLAPIENTRY +_mesa_ClearBufferfv_no_error(GLenum buffer, GLint drawbuffer, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferfv(ctx, buffer, drawbuffer, value, true); +} + + +void GLAPIENTRY +_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferfv(ctx, buffer, drawbuffer, value, false); +} + + /** * The ClearBuffer framework is so complicated and so riddled with the * assumption that the framebuffer is bound that, for now, we will just fake @@ -587,33 +658,34 @@ _mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, * New in GL 3.0 * Clear depth/stencil buffer only. */ -void GLAPIENTRY -_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, - GLfloat depth, GLint stencil) +static ALWAYS_INLINE void +clear_bufferfi(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, + GLfloat depth, GLint stencil, bool no_error) { - GET_CURRENT_CONTEXT(ctx); GLbitfield mask = 0; FLUSH_VERTICES(ctx, 0); FLUSH_CURRENT(ctx, 0); - if (buffer != GL_DEPTH_STENCIL) { - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", - _mesa_enum_to_string(buffer)); - return; - } + if (!no_error) { + if (buffer != GL_DEPTH_STENCIL) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", + _mesa_enum_to_string(buffer)); + return; + } - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "ClearBuffer generates an INVALID VALUE error if buffer is - * COLOR and drawbuffer is less than zero, or greater than the - * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, - * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", - drawbuffer); - return; + /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: + * + * "ClearBuffer generates an INVALID VALUE error if buffer is + * COLOR and drawbuffer is less than zero, or greater than the + * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, + * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." + */ + if (drawbuffer != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", + drawbuffer); + return; + } } if (ctx->RasterDiscard) @@ -647,6 +719,24 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, } +void GLAPIENTRY +_mesa_ClearBufferfi_no_error(GLenum buffer, GLint drawbuffer, + GLfloat depth, GLint stencil) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, true); +} + + +void GLAPIENTRY +_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, + GLfloat depth, GLint stencil) +{ + GET_CURRENT_CONTEXT(ctx); + clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, false); +} + + /** * The ClearBuffer framework is so complicated and so riddled with the * assumption that the framebuffer is bound that, for now, we will just fake