X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fdrawpix.c;h=828199ea5dd618cb73d171c1f5880118fe3f40c4;hb=ee0263e03fbc897767bf8b787dc0cc917481e826;hp=c9e714b210a7d1d026d73beddc26eb2270ac9056;hpb=887c349d543d5b6d681845eb441be88acb8e0063;p=mesa.git diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index c9e714b210a..828199ea5dd 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.1 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -17,13 +16,14 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "glheader.h" -#include "imports.h" +#include "draw_validate.h" #include "bufferobj.h" #include "context.h" #include "drawpix.h" @@ -31,35 +31,35 @@ #include "feedback.h" #include "framebuffer.h" #include "image.h" -#include "mfeatures.h" #include "pbo.h" -#include "readpix.h" #include "state.h" -#include "dispatch.h" - - -#if FEATURE_drawpix +#include "glformats.h" +#include "fbobject.h" +#include "util/u_math.h" +#include "util/rounding.h" /* * Execute glDrawPixels */ -static void GLAPIENTRY +void GLAPIENTRY _mesa_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ) { + GLenum err; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + FLUSH_VERTICES(ctx, 0); if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glDrawPixels(%d, %d, %s, %s, %p) // to %s at %d, %d\n", + _mesa_debug(ctx, "glDrawPixels(%d, %d, %s, %s, %p) // to %s at %ld, %ld\n", width, height, - _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), + _mesa_enum_to_string(format), + _mesa_enum_to_string(type), pixels, - _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]), - IROUND(ctx->Current.RasterPos[0]), - IROUND(ctx->Current.RasterPos[1])); + _mesa_enum_to_string(ctx->DrawBuffer->ColorDrawBuffer[0]), + lroundf(ctx->Current.RasterPos[0]), + lroundf(ctx->Current.RasterPos[1])); if (width < 0 || height < 0) { @@ -89,16 +89,48 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, * input), NVIDIA's implementation also just returns this error despite * exposing GL_EXT_texture_integer, just return an error regardless. */ - if (_mesa_is_integer_format(format)) { + if (_mesa_is_enum_format_integer(format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(integer format)"); goto end; } - if (_mesa_error_check_format_type(ctx, format, type, GL_TRUE)) { - goto end; /* the error code was recorded */ + err = _mesa_error_check_format_and_type(ctx, format, type); + if (err != GL_NO_ERROR) { + _mesa_error(ctx, err, "glDrawPixels(invalid format %s and/or type %s)", + _mesa_enum_to_string(format), + _mesa_enum_to_string(type)); + goto end; } - if (ctx->TransformFeedback.RasterDiscard) { + /* do special format-related checks */ + switch (format) { + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_EXT: + /* these buffers must exist */ + if (!_mesa_dest_buffer_exists(ctx, format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(missing dest buffer)"); + goto end; + } + break; + case GL_COLOR_INDEX: + if (ctx->PixelMaps.ItoR.Size == 0 || + ctx->PixelMaps.ItoG.Size == 0 || + ctx->PixelMaps.ItoB.Size == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(drawing color index pixels into RGB buffer)"); + goto end; + } + break; + default: + /* for color formats it's not an error if the destination color + * buffer doesn't exist. + */ + break; + } + + if (ctx->RasterDiscard) { goto end; } @@ -109,10 +141,10 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, if (ctx->RenderMode == GL_RENDER) { if (width > 0 && height > 0) { /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ - GLint x = IROUND(ctx->Current.RasterPos[0]); - GLint y = IROUND(ctx->Current.RasterPos[1]); + GLint x = lroundf(ctx->Current.RasterPos[0]); + GLint y = lroundf(ctx->Current.RasterPos[1]); - if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { + if (ctx->Unpack.BufferObj) { /* unpack from PBO */ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, format, type, INT_MAX, pixels)) { @@ -120,7 +152,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, "glDrawPixels(invalid PBO access)"); goto end; } - if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) { + if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) { /* buffer is mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)"); @@ -142,31 +174,36 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, ctx->Current.RasterTexCoords[0] ); } else { - ASSERT(ctx->RenderMode == GL_SELECT); + assert(ctx->RenderMode == GL_SELECT); /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */ } end: _mesa_set_vp_override(ctx, GL_FALSE); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } -static void GLAPIENTRY +void GLAPIENTRY _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLenum type ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + FLUSH_VERTICES(ctx, 0); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, - "glCopyPixels(%d, %d, %d, %d, %s) // from %s to %s at %d, %d\n", + "glCopyPixels(%d, %d, %d, %d, %s) // from %s to %s at %ld, %ld\n", srcx, srcy, width, height, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(ctx->ReadBuffer->ColorReadBuffer), - _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]), - IROUND(ctx->Current.RasterPos[0]), - IROUND(ctx->Current.RasterPos[1])); + _mesa_enum_to_string(type), + _mesa_enum_to_string(ctx->ReadBuffer->ColorReadBuffer), + _mesa_enum_to_string(ctx->DrawBuffer->ColorDrawBuffer[0]), + lroundf(ctx->Current.RasterPos[0]), + lroundf(ctx->Current.RasterPos[1])); if (width < 0 || height < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)"); @@ -182,7 +219,7 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, type != GL_STENCIL && type != GL_DEPTH_STENCIL) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)", - _mesa_lookup_enum_by_nr(type)); + _mesa_enum_to_string(type)); return; } @@ -203,6 +240,13 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, goto end; } + if (_mesa_is_user_fbo(ctx->ReadBuffer) && + ctx->ReadBuffer->Visual.samples > 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyPixels(multisample FBO)"); + goto end; + } + if (!_mesa_source_buffer_exists(ctx, type) || !_mesa_dest_buffer_exists(ctx, type)) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -210,7 +254,7 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, goto end; } - if (ctx->TransformFeedback.RasterDiscard) { + if (ctx->RasterDiscard) { goto end; } @@ -221,8 +265,8 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, if (ctx->RenderMode == GL_RENDER) { /* Round to satisfy conformance tests (matches SGI's OpenGL) */ if (width > 0 && height > 0) { - GLint destx = IROUND(ctx->Current.RasterPos[0]); - GLint desty = IROUND(ctx->Current.RasterPos[1]); + GLint destx = lroundf(ctx->Current.RasterPos[0]); + GLint desty = lroundf(ctx->Current.RasterPos[1]); ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type ); } @@ -230,28 +274,33 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, else if (ctx->RenderMode == GL_FEEDBACK) { FLUSH_CURRENT( ctx, 0 ); _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN ); - _mesa_feedback_vertex( ctx, + _mesa_feedback_vertex( ctx, ctx->Current.RasterPos, ctx->Current.RasterColor, ctx->Current.RasterTexCoords[0] ); } else { - ASSERT(ctx->RenderMode == GL_SELECT); + assert(ctx->RenderMode == GL_SELECT); /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */ } end: _mesa_set_vp_override(ctx, GL_FALSE); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } -static void GLAPIENTRY +void GLAPIENTRY _mesa_Bitmap( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + FLUSH_VERTICES(ctx, 0); if (width < 0 || height < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" ); @@ -268,17 +317,17 @@ _mesa_Bitmap( GLsizei width, GLsizei height, return; } - if (ctx->TransformFeedback.RasterDiscard) + if (ctx->RasterDiscard) return; if (ctx->RenderMode == GL_RENDER) { /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ if (width > 0 && height > 0) { const GLfloat epsilon = 0.0001F; - GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig); - GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig); + GLint x = util_ifloor(ctx->Current.RasterPos[0] + epsilon - xorig); + GLint y = util_ifloor(ctx->Current.RasterPos[1] + epsilon - yorig); - if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { + if (ctx->Unpack.BufferObj) { /* unpack from PBO */ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, GL_COLOR_INDEX, GL_BITMAP, @@ -287,7 +336,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, "glBitmap(invalid PBO access)"); return; } - if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) { + if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) { /* buffer is mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); @@ -298,7 +347,6 @@ _mesa_Bitmap( GLsizei width, GLsizei height, ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); } } -#if _HAVE_FULL_GL else if (ctx->RenderMode == GL_FEEDBACK) { FLUSH_CURRENT(ctx, 0); _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN ); @@ -308,24 +356,15 @@ _mesa_Bitmap( GLsizei width, GLsizei height, ctx->Current.RasterTexCoords[0] ); } else { - ASSERT(ctx->RenderMode == GL_SELECT); + assert(ctx->RenderMode == GL_SELECT); /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */ } -#endif /* update raster position */ ctx->Current.RasterPos[0] += xmove; ctx->Current.RasterPos[1] += ymove; -} - -void -_mesa_init_drawpix_dispatch(struct _glapi_table *disp) -{ - SET_Bitmap(disp, _mesa_Bitmap); - SET_CopyPixels(disp, _mesa_CopyPixels); - SET_DrawPixels(disp, _mesa_DrawPixels); + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } - - -#endif /* FEATURE_drawpix */