From 5c39bad220c801490ac3d99af01d4c4a7e05dfd6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 25 Sep 2008 19:11:03 -0700 Subject: intel: Add acceleration for glDrawPixels(GL_STENCIL_INDEX). This is nasty because there's no way in GL to output data to the stencil buffer directly, so we have to do a dance to wrap the depth/stencil buffer in an ARGB renderbuffer. Improves performance of several oglconform testcases by better than a factor of 2. --- src/mesa/drivers/dri/intel/intel_pixel_draw.c | 197 +++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index b60dad7460..50518a6879 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -40,6 +40,12 @@ #include "main/varray.h" #include "main/attrib.h" #include "main/enable.h" +#include "main/buffers.h" +#include "main/fbobject.h" +#include "main/renderbuffer.h" +#include "main/depth.h" +#include "main/hash.h" +#include "main/blend.h" #include "glapi/dispatch.h" #include "swrast/swrast.h" @@ -51,7 +57,7 @@ #include "intel_regions.h" #include "intel_pixel.h" #include "intel_buffer_objects.h" - +#include "intel_fbo.h" static GLboolean intel_texture_drawpixels(GLcontext * ctx, @@ -89,6 +95,15 @@ intel_texture_drawpixels(GLcontext * ctx, if (format == GL_STENCIL_INDEX) return GL_FALSE; + /* Check that we can load in a texture this big. */ + if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) || + height > (1 << (ctx->Const.MaxTextureLevels - 1))) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "glDrawPixels() fallback: bitmap too large (%dx%d)\n", + width, height); + return GL_FALSE; + } + /* To do DEPTH_COMPONENT, we would need to change our setup to not draw to * the color buffer, and sample the texture values into the fragment depth * in a program. @@ -170,6 +185,182 @@ intel_texture_drawpixels(GLcontext * ctx, return GL_TRUE; } +static GLboolean +intel_stencil_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels) +{ + GLuint texname, rb_name, fb_name, old_fb_name; + GLfloat vertices[4][2]; + GLfloat texcoords[4][2]; + struct intel_renderbuffer *irb; + struct intel_renderbuffer *depth_irb; + struct gl_renderbuffer *rb; + struct gl_pixelstore_attrib old_unpack; + GLstencil *stencil_pixels; + int row; + + if (format != GL_STENCIL_INDEX) + return GL_FALSE; + + /* If there's nothing to write, we're done. */ + if (ctx->Stencil.WriteMask[0] == 0) + return GL_TRUE; + + /* Can't do a per-bit writemask while treating stencil as rgba data. */ + if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) + return GL_FALSE; + + /* We use FBOs for our wrapping of the depthbuffer into a color + * destination. + */ + if (!ctx->Extensions.EXT_framebuffer_object) + return GL_FALSE; + + /* We're going to mess with texturing with no regard to existing texture + * state, so if there is some set up we have to bail. + */ + if (ctx->Texture._EnabledUnits != 0) + return GL_FALSE; + + /* Can't do textured DrawPixels with a fragment program, unless we were + * to generate a new program that sampled our texture and put the results + * in the fragment color before the user's program started. + */ + if (ctx->FragmentProgram.Enabled) + return GL_FALSE; + + /* Check that we can load in a texture this big. */ + if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) || + height > (1 << (ctx->Const.MaxTextureLevels - 1))) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "glDrawPixels(STENCIL_IDNEX) fallback: " + "bitmap too large (%dx%d)\n", + width, height); + return GL_FALSE; + } + + _mesa_PushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_TEXTURE_BIT | + GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + old_fb_name = ctx->DrawBuffer->Name; + + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_DEPTH_TEST); + _mesa_Disable(GL_STENCIL_TEST); + + /* Unpack the supplied stencil values into a ubyte buffer. */ + assert(sizeof(GLstencil) == sizeof(GLubyte)); + stencil_pixels = _mesa_malloc(width * height * sizeof(GLstencil)); + for (row = 0; row < height; row++) { + GLvoid *source = _mesa_image_address2d(unpack, pixels, + width, height, + GL_COLOR_INDEX, type, + row, 0); + _mesa_unpack_stencil_span(ctx, width, GL_UNSIGNED_BYTE, + stencil_pixels + + row * width * sizeof(GLstencil), + type, source, unpack, ctx->_ImageTransferState); + } + + /* Take the current depth/stencil renderbuffer, and make a new one wrapping + * it which will be treated as GL_RGBA8 so we can render to it as a color + * buffer. + */ + depth_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH); + irb = intel_create_renderbuffer(GL_RGBA8); + rb = &irb->Base; + irb->Base.Width = depth_irb->Base.Width; + irb->Base.Height = depth_irb->Base.Height; + intel_renderbuffer_set_region(irb, depth_irb->region); + + /* Create a name for our renderbuffer, which lets us use other mesa + * rb functions for convenience. + */ + _mesa_GenRenderbuffersEXT(1, &rb_name); + irb->Base.RefCount++; + _mesa_HashInsert(ctx->Shared->RenderBuffers, rb_name, &irb->Base); + + /* Bind the new renderbuffer to the color attachment point. */ + _mesa_GenFramebuffersEXT(1, &fb_name); + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name); + _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + rb_name); + /* Choose to render to the color attachment. */ + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + + _mesa_DepthMask(GL_FALSE); + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB); + _mesa_Enable(GL_TEXTURE_2D); + _mesa_GenTextures(1, &texname); + _mesa_BindTexture(GL_TEXTURE_2D, texname); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + _mesa_TexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + old_unpack = ctx->Unpack; + ctx->Unpack = ctx->DefaultPacking; + _mesa_TexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, + GL_RED, GL_UNSIGNED_BYTE, stencil_pixels); + ctx->Unpack = old_unpack; + _mesa_free(stencil_pixels); + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); + _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); + + vertices[0][0] = x; + vertices[0][1] = y; + vertices[1][0] = x + width * ctx->Pixel.ZoomX; + vertices[1][1] = y; + vertices[2][0] = x + width * ctx->Pixel.ZoomX; + vertices[2][1] = y + height * ctx->Pixel.ZoomY; + vertices[3][0] = x; + vertices[3][1] = y + height * ctx->Pixel.ZoomY; + + texcoords[0][0] = 0.0; + texcoords[0][1] = 0.0; + texcoords[1][0] = 1.0; + texcoords[1][1] = 0.0; + texcoords[2][0] = 1.0; + texcoords[2][1] = 1.0; + texcoords[3][0] = 0.0; + texcoords[3][1] = 1.0; + + _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); + _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); + _mesa_Enable(GL_VERTEX_ARRAY); + _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name); + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PopMatrix(); + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PopMatrix(); + _mesa_PopClientAttrib(); + _mesa_PopAttrib(); + + _mesa_DeleteTextures(1, &texname); + _mesa_DeleteFramebuffersEXT(1, &fb_name); + _mesa_DeleteRenderbuffersEXT(1, &rb_name); + + return GL_TRUE; +} + void intelDrawPixels(GLcontext * ctx, GLint x, GLint y, @@ -183,6 +374,10 @@ intelDrawPixels(GLcontext * ctx, unpack, pixels)) return; + if (intel_stencil_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); -- cgit v1.2.3 From c238098bbcfb644ea01b33d3274b949d84822512 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 13 Oct 2008 13:04:04 +0800 Subject: i915: Texture instructions use r/t/oC/oD register as texture coordinate. Fix http://bugs.freedesktop.org/show_bug.cgi?id=16287. --- src/mesa/drivers/dri/i915/i915_program.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c index 350da5e169..e87700f8e0 100644 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ b/src/mesa/drivers/dri/i915/i915_program.c @@ -245,6 +245,19 @@ GLuint i915_emit_texld( struct i915_fragment_program *p, */ assert(GET_UREG_TYPE(coord) != REG_TYPE_U); + if ((GET_UREG_TYPE(coord) != REG_TYPE_R) && + (GET_UREG_TYPE(coord) != REG_TYPE_OC) && + (GET_UREG_TYPE(coord) != REG_TYPE_OD) && + (GET_UREG_TYPE(coord) != REG_TYPE_T)) { + GLuint tmpCoord = get_free_rreg(p, live_regs); + + if (tmpCoord == UREG_BAD) + return 0; + + i915_emit_arith(p, A0_MOV, tmpCoord, A0_DEST_CHANNEL_ALL, 0, coord, 0, 0); + coord = tmpCoord; + } + /* Output register being oC or oD defines a phase boundary */ if (GET_UREG_TYPE(dest) == REG_TYPE_OC || GET_UREG_TYPE(dest) == REG_TYPE_OD) -- cgit v1.2.3 From a7b24ac02f80efd83e93b4597a2c0e5a6ba198fe Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 16 Oct 2008 08:23:28 -0600 Subject: mesa: fix error codes in _mesa_GetObjectParameterivARB(), bug 17861 --- src/mesa/main/shaders.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c index e5c54bb10d..7491d00c35 100644 --- a/src/mesa/main/shaders.c +++ b/src/mesa/main/shaders.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. * @@ -235,30 +235,21 @@ _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params) if (ctx->Driver.IsProgram(ctx, object)) { if (pname == GL_OBJECT_TYPE_ARB) { *params = GL_PROGRAM_OBJECT_ARB; - } else { + } + else { ctx->Driver.GetProgramiv(ctx, object, pname, params); } } else if (ctx->Driver.IsShader(ctx, object)) { if (pname == GL_OBJECT_TYPE_ARB) { *params = GL_SHADER_OBJECT_ARB; - } else { + } + else { ctx->Driver.GetShaderiv(ctx, object, pname, params); } } else { - /* error code depends on pname */ - GLenum err; - switch (pname) { - case GL_OBJECT_TYPE_ARB: - case GL_OBJECT_DELETE_STATUS_ARB: - case GL_OBJECT_INFO_LOG_LENGTH_ARB: - err = GL_INVALID_OPERATION; - break; - default: - err = GL_INVALID_VALUE; - } - _mesa_error(ctx, err, "glGetObjectParameterivARB"); + _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); } } -- cgit v1.2.3 From 73e119363216b75243dce170f8afd5c2f9bfce50 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 16 Oct 2008 16:23:47 +0200 Subject: fix span issue with really old ddx and non-tcl r100 chips --- src/mesa/drivers/dri/radeon/radeon_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 05107dd2ad..5f32dd575e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -900,7 +900,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->depthHasSurface = (sPriv->ddx_version.major > 4) || /* these chips don't use tiled z without hyperz. So always pretend we have set up a surface which will cause linear reads/writes */ - ((screen->chip_family & RADEON_CLASS_R100) && + (IS_R100_CLASS(screen) && !(screen->chip_flags & RADEON_CHIPSET_TCL)); if ( dri_priv->textureSize == 0 ) { -- cgit v1.2.3 From b4bf9acc32ac8693b1fdf80f351523a468ba6bd1 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 21 Oct 2008 10:30:39 +0800 Subject: i915: fix carsh in i830_emit_state. (bug #17766) --- src/mesa/drivers/dri/i915/i830_vtbl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 773a8b4dd0..3c9851e63f 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -449,7 +449,8 @@ i830_emit_state(struct intel_context *intel) aper_array[aper_count++] = intel->batch->buf; if (dirty & I830_UPLOAD_BUFFERS) { aper_array[aper_count++] = state->draw_region->buffer; - aper_array[aper_count++] = state->depth_region->buffer; + if (state->depth_region) + aper_array[aper_count++] = state->depth_region->buffer; } for (i = 0; i < I830_TEX_UNITS; i++) -- cgit v1.2.3 From 22e442544bc451f114288f07cf9cc1584ca357a1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Oct 2008 07:36:33 -0600 Subject: mesa: in textore.c, only adjust image for convolution if image is a color format Makes things consistant with the code in teximage.c. We only want to apply convolution to color formats (not depth/index formats) --- src/mesa/main/teximage.c | 27 +++++++++++++++------------ src/mesa/main/teximage.h | 3 +++ src/mesa/main/texstore.c | 4 ++-- 3 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 4a419fde26..1838e41e48 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -388,9 +388,10 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat ) * index, depth, stencil, etc). * \param format the image format value (may by an internal texture format) * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise. + * XXX maybe move this func to image.c */ -static GLboolean -is_color_format(GLenum format) +GLboolean +_mesa_is_color_format(GLenum format) { switch (format) { case GL_RED: @@ -491,6 +492,7 @@ is_color_format(GLenum format) #endif /* FEATURE_EXT_texture_sRGB */ return GL_TRUE; case GL_YCBCR_MESA: /* not considered to be RGB */ + /* fall-through */ default: return GL_FALSE; } @@ -1576,9 +1578,9 @@ texture_error_check( GLcontext *ctx, GLenum target, } /* make sure internal format and format basically agree */ - colorFormat = is_color_format(format); + colorFormat = _mesa_is_color_format(format); indexFormat = is_index_format(format); - if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) || + if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || (is_index_format(internalFormat) && !indexFormat) || (is_depth_format(internalFormat) != is_depth_format(format)) || (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) || @@ -2325,8 +2327,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, * texture's format. Note that a color index texture can be converted * to RGBA so that combo is allowed. */ - if (is_color_format(format) - && !is_color_format(texImage->TexFormat->BaseFormat) + if (_mesa_is_color_format(format) + && !_mesa_is_color_format(texImage->TexFormat->BaseFormat) && !is_index_format(texImage->TexFormat->BaseFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); goto out; @@ -2419,7 +2421,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } #endif @@ -2516,7 +2518,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } @@ -2741,7 +2743,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level, #if FEATURE_convolve /* XXX should test internal format */ - if (is_color_format(format)) { + if (_mesa_is_color_format(format)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } #endif @@ -2801,7 +2803,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level, #if FEATURE_convolve /* XXX should test internal format */ - if (is_color_format(format)) { + if (_mesa_is_color_format(format)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } @@ -2916,7 +2918,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, _mesa_update_state(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } #endif @@ -2981,7 +2983,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, _mesa_update_state(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } @@ -3048,6 +3050,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, _mesa_update_state(ctx); #if FEATURE_convolve + /* XXX should test internal format */ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); #endif diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index b718c0046d..eb60a1fa8f 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -111,6 +111,9 @@ extern GLuint _mesa_tex_target_to_face(GLenum target); +extern GLboolean +_mesa_is_color_format(GLenum format); + /** * Lock a texture for updating. See also _mesa_lock_context_textures(). diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 75b14c2bf0..a5cf52b5a6 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -3006,7 +3006,7 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, GLint sizeInBytes; (void) border; - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } @@ -3080,7 +3080,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, GLint texelBytes, sizeInBytes; (void) border; - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } -- cgit v1.2.3 From 9dfd54fa83f9d2266ee637721365f8922deb17fc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Oct 2008 07:48:37 -0600 Subject: mesa: some re-org of glCopyTexSubImage1/2/3D() error checking --- src/mesa/main/teximage.c | 65 ++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 33 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 1838e41e48..4c48370d9d 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -2042,30 +2042,20 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, /** * Test glCopyTexSubImage[12]D() parameters for errors. + * Note that this is the first part of error checking. + * See also copytexsubimage_error_check2() below for the second part. * * \param ctx GL context. * \param dimensions texture image dimensions (must be 1, 2 or 3). * \param target texture target given by the user. * \param level image level given by the user. - * \param xoffset sub-image x offset given by the user. - * \param yoffset sub-image y offset given by the user. - * \param zoffset sub-image z offset given by the user. - * \param width image width given by the user. - * \param height image height given by the user. * * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. - * - * Verifies each of the parameters against the constants specified in - * __GLcontextRec::Const and the supported extensions, and according to the - * OpenGL specification. */ static GLboolean -copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height) +copytexsubimage_error_check1( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level) { - /* Check target */ /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); @@ -2076,6 +2066,7 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, } } + /* Check target */ if (dimensions == 1) { if (target != GL_TEXTURE_1D) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); @@ -2123,21 +2114,18 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - /* Check size */ - if (width < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexSubImage%dD(width=%d)", dimensions, width); - return GL_TRUE; - } - if (dimensions > 1 && height < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexSubImage%dD(height=%d)", dimensions, height); - return GL_TRUE; - } - return GL_FALSE; } + +/** + * Second part of error checking for glCopyTexSubImage[12]D(). + * \param xoffset sub-image x offset given by the user. + * \param yoffset sub-image y offset given by the user. + * \param zoffset sub-image z offset given by the user. + * \param width image width given by the user. + * \param height image height given by the user. + */ static GLboolean copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, @@ -2145,6 +2133,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, GLsizei width, GLsizei height, const struct gl_texture_image *teximage ) { + /* check that dest tex image exists */ if (!teximage) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%dD(undefined texture level: %d)", @@ -2152,6 +2141,19 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } + /* Check size */ + if (width < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%dD(width=%d)", dimensions, width); + return GL_TRUE; + } + if (dimensions > 1 && height < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%dD(height=%d)", dimensions, height); + return GL_TRUE; + } + + /* check x/y offsets */ if (xoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); @@ -2176,6 +2178,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, } } + /* check z offset */ if (dimensions > 2) { if (zoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -3050,13 +3053,11 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, _mesa_update_state(ctx); #if FEATURE_convolve - /* XXX should test internal format */ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); #endif - if (copytexsubimage_error_check(ctx, 1, target, level, - xoffset, 0, 0, postConvWidth, 1)) + if (copytexsubimage_error_check1(ctx, 1, target, level)) return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -3110,8 +3111,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); #endif - if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0, - postConvWidth, postConvHeight)) + if (copytexsubimage_error_check1(ctx, 2, target, level)) return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -3164,8 +3164,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); #endif - if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset, - zoffset, postConvWidth, postConvHeight)) + if (copytexsubimage_error_check1(ctx, 3, target, level)) return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; -- cgit v1.2.3 From 95c04cccfef2e5743279e1f5a6a13f3925c7024c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Oct 2008 07:53:26 -0600 Subject: mesa: move convolution image adjustment code for glCopyTexSubImage1/2/3D() Do it after initial error checking, after we know the texture's internal format. --- src/mesa/main/teximage.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 4c48370d9d..f9360b474e 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -2991,6 +2991,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, &postConvHeight); } #endif + if (copytexture_error_check(ctx, 2, target, level, internalFormat, postConvWidth, postConvHeight, border)) return; @@ -3052,11 +3053,6 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); -#if FEATURE_convolve - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); -#endif - if (copytexsubimage_error_check1(ctx, 1, target, level)) return; @@ -3067,6 +3063,12 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); +#if FEATURE_convolve + if (texImage && _mesa_is_color_format(texImage->InternalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + } +#endif + if (copytexsubimage_error_check2(ctx, 1, target, level, xoffset, 0, 0, postConvWidth, 1, texImage)) @@ -3106,11 +3108,6 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); -#if FEATURE_convolve - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); -#endif - if (copytexsubimage_error_check1(ctx, 2, target, level)) return; @@ -3121,6 +3118,13 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); +#if FEATURE_convolve + if (texImage && _mesa_is_color_format(texImage->InternalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 2, + &postConvWidth, &postConvHeight); + } +#endif + if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, postConvWidth, postConvHeight, texImage)) goto out; @@ -3159,11 +3163,6 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); -#if FEATURE_convolve - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); -#endif - if (copytexsubimage_error_check1(ctx, 3, target, level)) return; @@ -3174,6 +3173,13 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); +#if FEATURE_convolve + if (texImage && _mesa_is_color_format(texImage->InternalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 2, + &postConvWidth, &postConvHeight); + } +#endif + if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset, postConvWidth, postConvHeight, texImage)) -- cgit v1.2.3 From ea6ddcbe0e4a0049ee8b9d244d86b6981fc6438b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 23 Oct 2008 10:49:51 -0600 Subject: mesa: remove calls to _mesa_adjust_image_for_convolution(), use texImage fields The texImage->Width/Height fields will have the post-convolution width/height. --- src/mesa/main/texstore.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index a5cf52b5a6..abeed3baa1 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -2988,10 +2988,13 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage, -/* +/** * This is the software fallback for Driver.TexImage1D() * and Driver.CopyTexImage1D(). * \sa _mesa_store_teximage2d() + * Note that the width may not be the actual texture width since it may + * be changed by convolution w/ GL_REDUCE. The texImage->Width field will + * have the actual texture size. */ void _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, @@ -3002,21 +3005,16 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLint postConvWidth = width; GLint sizeInBytes; (void) border; - if (_mesa_is_color_format(internalFormat)) { - _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); - } - choose_texture_format(ctx, texImage, 1, format, type, internalFormat); /* allocate memory */ if (texImage->IsCompressed) sizeInBytes = texImage->CompressedSize; else - sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes; + sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes; texImage->Data = _mesa_alloc_texmemory(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); @@ -3076,15 +3074,9 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLint postConvWidth = width, postConvHeight = height; GLint texelBytes, sizeInBytes; (void) border; - if (_mesa_is_color_format(internalFormat)) { - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, - &postConvHeight); - } - choose_texture_format(ctx, texImage, 2, format, type, internalFormat); texelBytes = texImage->TexFormat->TexelBytes; @@ -3093,7 +3085,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, if (texImage->IsCompressed) sizeInBytes = texImage->CompressedSize; else - sizeInBytes = postConvWidth * postConvHeight * texelBytes; + sizeInBytes = texImage->Width * texImage->Height * texelBytes; texImage->Data = _mesa_alloc_texmemory(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); -- cgit v1.2.3 From f657c8191128c500c2aa7204009154a1182e2abd Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 24 Oct 2008 15:55:32 +0800 Subject: intel: fallback for intelEmitCopyBlit. Use _mesa_copy_rect instead of BLT operation if dri_bufmgr_check_aperture_space still fails after flushing batchbuffer. Partial fix for #17964. --- src/mesa/drivers/dri/intel/intel_blit.c | 49 ++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 2917401e02..081d1dd238 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -272,24 +272,53 @@ intelEmitCopyBlit(struct intel_context *intel, GLshort w, GLshort h, GLenum logic_op) { - GLuint CMD, BR13; + GLuint CMD, BR13, pass = 0; int dst_y2 = dst_y + h; int dst_x2 = dst_x + w; dri_bo *aper_array[3]; BATCH_LOCALS; /* do space/cliprects check before going any further */ - intel_batchbuffer_require_space(intel->batch, 8 * 4, NO_LOOP_CLIPRECTS); - again: - aper_array[0] = intel->batch->buf; - aper_array[1] = dst_buffer; - aper_array[2] = src_buffer; - - if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) { - intel_batchbuffer_flush(intel->batch); - goto again; + do { + aper_array[0] = intel->batch->buf; + aper_array[1] = dst_buffer; + aper_array[2] = src_buffer; + + if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) { + intel_batchbuffer_flush(intel->batch); + pass++; + } else + break; + } while (pass < 2); + + if (pass >= 2) { + GLboolean locked = GL_FALSE; + if (!intel->locked) { + LOCK_HARDWARE(intel); + locked = GL_TRUE; + } + + dri_bo_map(dst_buffer, GL_TRUE); + dri_bo_map(src_buffer, GL_TRUE); + _mesa_copy_rect((GLubyte *)dst_buffer->virtual + dst_offset, + cpp, + dst_pitch, + dst_x, dst_y, + w, h, + (GLubyte *)src_buffer->virtual + src_offset, + src_pitch, + src_x, src_y); + + dri_bo_unmap(src_buffer); + dri_bo_unmap(dst_buffer); + + if (locked) + UNLOCK_HARDWARE(intel); + + return; } + intel_batchbuffer_require_space(intel->batch, 8 * 4, NO_LOOP_CLIPRECTS); DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __FUNCTION__, src_buffer, src_pitch, src_offset, src_x, src_y, -- cgit v1.2.3 From ec8076264ea2390d4cb749be5c88bbf2bf5d4847 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 24 Oct 2008 16:05:48 +0800 Subject: i965: don't emit state when dri_bufmgr_check_aperture_space fails. This ensures there is an unfilled batchbuffer used for emitting states again. Partial fix for #17964. --- src/mesa/drivers/dri/i965/brw_curbe.c | 4 +++- src/mesa/drivers/dri/i965/brw_misc_state.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 7cddd3a7de..6ffa221d66 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -333,8 +333,10 @@ static void emit_constant_buffer(struct brw_context *brw) brw->curbe.curbe_bo, }; - if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) + if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) { intel_batchbuffer_flush(intel->batch); + return; + } BEGIN_BATCH(2, IGNORE_CLIPRECTS); if (sz == 0) { diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 487c638ce2..afa8694ebb 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -86,8 +86,10 @@ static void upload_binding_table_pointers(struct brw_context *brw) brw->wm.bind_bo, }; - if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) + if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) { intel_batchbuffer_flush(intel->batch); + return; + } BEGIN_BATCH(6, IGNORE_CLIPRECTS); OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2)); @@ -152,8 +154,10 @@ static void upload_psp_urb_cbs(struct brw_context *brw ) brw->cc.state_bo, }; - if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) + if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) { intel_batchbuffer_flush(intel->batch); + return; + } upload_pipelined_state_pointers(brw); brw_upload_urb_fence(brw); @@ -216,8 +220,10 @@ static void emit_depthbuffer(struct brw_context *brw) return; } - if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) + if (dri_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array))) { intel_batchbuffer_flush(intel->batch); + return; + } BEGIN_BATCH(len, IGNORE_CLIPRECTS); OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2)); -- cgit v1.2.3 From 2a877411dbe35abdd8c15fb4821d9232619d89cc Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Sun, 26 Oct 2008 06:31:33 +0800 Subject: intel: GL_FALSE on a BO if it won't be modified when mapping this BO. (thanks Eric). --- src/mesa/drivers/dri/intel/intel_blit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 081d1dd238..3c1f7f6245 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -299,7 +299,7 @@ intelEmitCopyBlit(struct intel_context *intel, } dri_bo_map(dst_buffer, GL_TRUE); - dri_bo_map(src_buffer, GL_TRUE); + dri_bo_map(src_buffer, GL_FALSE); _mesa_copy_rect((GLubyte *)dst_buffer->virtual + dst_offset, cpp, dst_pitch, -- cgit v1.2.3