X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fmain%2Fdrawpix.c;h=fdcbcccded294d41558336cdf3c25a93b92429a8;hb=f609cf782ab5e90ddf045dc4b0da8cebf99be0d1;hp=6fda3c5665c69577a03359485145827a5036fc0b;hpb=72e30991559017c16d48569e612dbc0970e3b9ca;p=mesa.git diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 6fda3c5665c..fdcbcccded2 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -30,8 +30,9 @@ #include "enums.h" #include "feedback.h" #include "framebuffer.h" +#include "image.h" #include "mfeatures.h" -#include "readpix.h" +#include "pbo.h" #include "state.h" #include "dispatch.h" @@ -46,11 +47,23 @@ static 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); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glDrawPixels(%d, %d, %s, %s, %p) // to %s at %d, %d\n", + width, height, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type), + pixels, + _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]), + IROUND(ctx->Current.RasterPos[0]), + IROUND(ctx->Current.RasterPos[1])); + + if (width < 0 || height < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0)" ); return; } @@ -64,8 +77,61 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, goto end; /* the error code was recorded */ } - if (_mesa_error_check_format_type(ctx, format, type, GL_TRUE)) { - goto end; /* the error code was recorded */ + /* GL 3.0 introduced a new restriction on glDrawPixels() over what was in + * GL_EXT_texture_integer. From section 3.7.4 ("Rasterization of Pixel + * Rectangles) on page 151 of the GL 3.0 specification: + * + * "If format contains integer components, as shown in table 3.6, an + * INVALID OPERATION error is generated." + * + * Since DrawPixels rendering would be merely undefined if not an error (due + * to a lack of defined mapping from integer data to gl_Color fragment shader + * 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)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(integer format)"); + goto end; + } + + 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_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type)); + goto end; + } + + /* 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 deest 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; } if (!ctx->Current.RasterPosValid) { @@ -78,10 +144,10 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, GLint x = IROUND(ctx->Current.RasterPos[0]); GLint y = IROUND(ctx->Current.RasterPos[1]); - if (ctx->Unpack.BufferObj->Name) { + if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { /* unpack from PBO */ - if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, - format, type, pixels)) { + if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, + 1, format, type, INT_MAX, pixels)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(invalid PBO access)"); goto end; @@ -114,6 +180,10 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, end: _mesa_set_vp_override(ctx, GL_FALSE); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -124,6 +194,16 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, + "glCopyPixels(%d, %d, %d, %d, %s) // from %s to %s at %d, %d\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])); + if (width < 0 || height < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)"); return; @@ -159,6 +239,12 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, goto end; } + if (ctx->ReadBuffer->Name != 0 && 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, @@ -166,7 +252,11 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, goto end; } - if (!ctx->Current.RasterPosValid || width ==0 || height == 0) { + if (ctx->RasterDiscard) { + goto end; + } + + if (!ctx->Current.RasterPosValid || width == 0 || height == 0) { goto end; /* no-op, not an error */ } @@ -194,6 +284,10 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, end: _mesa_set_vp_override(ctx, GL_FALSE); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -220,6 +314,9 @@ _mesa_Bitmap( GLsizei width, GLsizei height, return; } + if (ctx->RasterDiscard) + return; + if (ctx->RenderMode == GL_RENDER) { /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ if (width > 0 && height > 0) { @@ -227,11 +324,11 @@ _mesa_Bitmap( GLsizei width, GLsizei height, GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig); GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig); - if (ctx->Unpack.BufferObj->Name) { + if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { /* unpack from PBO */ - if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, - GL_COLOR_INDEX, GL_BITMAP, - (GLvoid *) bitmap)) { + if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, + 1, GL_COLOR_INDEX, GL_BITMAP, + INT_MAX, (const GLvoid *) bitmap)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(invalid PBO access)"); return; @@ -265,6 +362,10 @@ _mesa_Bitmap( GLsizei width, GLsizei height, /* update raster position */ ctx->Current.RasterPos[0] += xmove; ctx->Current.RasterPos[1] += ymove; + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } }