diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index d1dd2d6a513..e68fc3c634e 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -7,6 +7,7 @@ LIBNAME = i915_dri.so DRIVER_SOURCES = \ bufmgr_fake.c \ intel_regions.c \ + intel_buffer_objects.c \ intel_batchbuffer.c \ intel_mipmap_tree.c \ i915_tex_layout.c \ diff --git a/src/mesa/drivers/dri/i915/intel_buffer_objects.c b/src/mesa/drivers/dri/i915/intel_buffer_objects.c index c08ca14ac2e..a59211e961c 100644 --- a/src/mesa/drivers/dri/i915/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915/intel_buffer_objects.c @@ -40,11 +40,6 @@ struct intel_buffer_object { GLuint buffer; }; -static inline struct intel_buffer_object * -intel_buffer_object( struct gl_buffer_object *obj ) -{ - return (struct intel_buffer_object *)obj; -} /* There is some duplication between mesa's bufferobjects and our * bufmgr buffers. Both have an integer handle and a hashtable to @@ -62,7 +57,7 @@ static struct gl_buffer_object *intel_bufferobj_alloc( GLcontext *ctx, /* XXX: We generate our own handle, which is different to 'name' above. */ - bmGenBuffers(intel->bm, &obj->buffer, 1); + bmGenBuffers(intel->bm, 1, &obj->buffer); return &obj->Base; } @@ -70,20 +65,15 @@ static struct gl_buffer_object *intel_bufferobj_alloc( GLcontext *ctx, static void intel_bufferobj_free( GLcontext *ctx, struct gl_buffer_object *obj ) { - /* Are the obj->Name tests necessary? Unfortunately yes, mesa - * allocates a couple of gl_buffer_object structs statically, and - * the Name == 0 test is the only way to identify them and avoid - * casting them erroneously to our structs. - */ - if (obj->Name) { - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - if (intel_obj->buffer) - bmDeleteBuffers( intel->bm, 1, &intel_obj->buffer ); + assert(intel_obj); + + if (intel_obj->buffer) + bmDeleteBuffers( intel->bm, 1, &intel_obj->buffer ); - _mesa_free(obj); - } + _mesa_free(intel_obj); } @@ -99,15 +89,14 @@ static void intel_bufferobj_data( GLcontext *ctx, GLenum usage, struct gl_buffer_object *obj ) { - if (obj->Name) { - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - /* XXX: do something useful with 'usage' (eg. populate flags - * argument below) - */ - bmBufferData(intel->bm, obj->buffer, size, data, 0); - } + /* XXX: do something useful with 'usage' (eg. populate flags + * argument below) + */ + assert(intel_obj); + bmBufferData(intel->bm, intel_obj->buffer, size, data, 0); } @@ -122,12 +111,11 @@ static void intel_bufferobj_subdata( GLcontext *ctx, const GLvoid * data, struct gl_buffer_object * obj ) { - if (obj->Name) { - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - bmBufferSubData(intel->bm, obj->buffer, size, data); - } + assert(intel_obj); + bmBufferSubData(intel->bm, intel_obj->buffer, offset, size, data); } @@ -138,16 +126,13 @@ static void *intel_bufferobj_map( GLcontext *ctx, GLenum access, struct gl_buffer_object *obj ) { - if (obj->Name) { - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - /* XXX: Translate access to flags arg below: - */ - return bmMapBuffer(intel->bm, intel_obj->buffer, 0); - } - - return NULL; + /* XXX: Translate access to flags arg below: + */ + assert(intel_obj); + return bmMapBuffer(intel->bm, intel_obj->buffer, 0); } @@ -155,37 +140,27 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, GLenum target, struct gl_buffer_object *obj ) { - if (obj->Name) { - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - return bmUnmapBuffer(intel->bm, intel_obj->buffer); - } - + assert(intel_obj); + bmUnmapBuffer(intel->bm, intel_obj->buffer); return GL_TRUE; } -GLuint intel_bufferobj_buffer( struct gl_buffer_object *obj ) +GLuint intel_bufferobj_buffer( struct intel_buffer_object *intel_obj ) { - if (obj->Name) { - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - return intel_obj->buffer; - } - else { - assert(0); - return 0; - } - + return intel_obj->buffer; } void intel_bufferobj_init( struct intel_context *intel ) { GLcontext *ctx = &intel->ctx; - ctx->Driver.NewBufferObject = intel_new_buffer_object; - ctx->Driver.DeleteBuffer = intel_delete_buffer_object; - ctx->Driver.BufferData = intel_buffer_data; - ctx->Driver.BufferSubData = intel_buffer_subdata; - ctx->Driver.MapBuffer = intel_buffer_map; - ctx->Driver.UnmapBuffer = intel_buffer_unmap; + ctx->Driver.NewBufferObject = intel_bufferobj_alloc; + ctx->Driver.DeleteBuffer = intel_bufferobj_free; + ctx->Driver.BufferData = intel_bufferobj_data; + ctx->Driver.BufferSubData = intel_bufferobj_subdata; + ctx->Driver.MapBuffer = intel_bufferobj_map; + ctx->Driver.UnmapBuffer = intel_bufferobj_unmap; } diff --git a/src/mesa/drivers/dri/i915/intel_buffer_objects.h b/src/mesa/drivers/dri/i915/intel_buffer_objects.h index 13782c79eff..e0f21de5443 100644 --- a/src/mesa/drivers/dri/i915/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i915/intel_buffer_objects.h @@ -32,14 +32,30 @@ struct intel_context; struct gl_buffer_object; +struct intel_buffer_object; /* Get the bm buffer associated with a GL bufferobject: */ -GLuint intel_bufferobj_buffer( struct intel_context *intel, - struct gl_buffer_object *obj ); +GLuint intel_bufferobj_buffer( struct intel_buffer_object *obj ); /* Hook the bufferobject implementation into mesa: */ void intel_bufferobj_init( struct intel_context *intel ); + + +/* Are the obj->Name tests necessary? Unfortunately yes, mesa + * allocates a couple of gl_buffer_object structs statically, and + * the Name == 0 test is the only way to identify them and avoid + * casting them erroneously to our structs. + */ +static inline struct intel_buffer_object * +intel_buffer_object( struct gl_buffer_object *obj ) +{ + if (obj->Name) + return (struct intel_buffer_object *)obj; + else + return NULL; +} + #endif diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 50510dac2b5..d006c0c5fdd 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -57,6 +57,7 @@ #include "intel_blit.h" #include "intel_pixel.h" #include "intel_regions.h" +#include "intel_buffer_objects.h" #include "bufmgr.h" @@ -154,6 +155,7 @@ const struct dri_extension card_extensions[] = { "GL_ARB_texture_mirrored_repeat", NULL }, { "GL_ARB_texture_rectangle", NULL }, { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, + { "GL_ARB_pixel_buffer_object", NULL }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, @@ -424,6 +426,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->height); intel->batch = intel_batchbuffer_alloc( intel ); + intel_bufferobj_init( intel ); if (intel->ctx.Mesa_DXTn) { _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); @@ -433,12 +436,6 @@ GLboolean intelInitContext( struct intel_context *intel, _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); } -/* driInitTextureObjects( ctx, & intel->swapped, */ -/* DRI_TEXMGR_DO_TEXTURE_1D | */ -/* DRI_TEXMGR_DO_TEXTURE_2D | */ -/* DRI_TEXMGR_DO_TEXTURE_RECT ); */ - - intel->prim.primitive = ~0; diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c index e80ecd4412d..83fa086ad29 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.c +++ b/src/mesa/drivers/dri/i915/intel_pixel.c @@ -1,42 +1,38 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portionsalloc + * of the Software. + * + * 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 "swrast/swrast.h" + #include "intel_context.h" #include "intel_pixel.h" #include "intel_regions.h" - -#if 0 -struct intel_client_region *intel_pack_region( struct intel_context *intel, - const struct gl_pixelstore_attrib *pack, - GLenum format, - GLenum type, - GLvoid *pixels ) -{ -} - - -struct intel_client_region *intel_unpack_region( struct intel_context *intel, - const struct gl_pixelstore_attrib *pack, - GLenum format, - GLenum type, - GLvoid *pixels ) -{ - GLint pitch = unpack->RowLength ? unpack->RowLength : width; - /* XXX: Need to adjust pixels pointer for unpack->skip pixels/rows - * offsets. - */ - -} - -void release_client_region( struct intel_context *intel, - struct intel_region *region ) -{ -} -#endif - - - -GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ) +GLboolean intel_check_blit_fragment_ops( const GLcontext *ctx ) { return !(ctx->Color.AlphaEnabled || ctx->Depth.Test || @@ -51,33 +47,29 @@ GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ) ctx->Texture._EnabledUnits); } -#if 0 /* The intel_region struct doesn't really do enough to capture the * format of the pixels in the region. For now this code assumes that * the region is a display surface and hence is either ARGB8888 or * RGB565. */ GLboolean intel_check_blit_format( struct intel_region *region, - struct intel_client_region *client_region ) + GLenum type, GLenum format ) { - if (region->cpp == 4 - client_region->cpp == 4 && - client_region->type == GL_UNSIGNED_INT_8_8_8_8_REV && - client_region->format == GL_BGRA ) { + if (region->cpp == 4 && + type == GL_UNSIGNED_INT_8_8_8_8_REV && + format == GL_BGRA ) { return GL_TRUE; } if (region->cpp == 2 && - client_region->cpp == 2 && - client_region->type == GL_UNSIGNED_INT_5_6_5_REV && - client_region->format == GL_BGR ) { + type == GL_UNSIGNED_SHORT_5_6_5_REV && + format == GL_BGR ) { return GL_TRUE; } fprintf(stderr, "%s: request doesn't match pixel format\n", __FUNCTION__); return GL_FALSE; } -#endif GLboolean intel_clip_to_framebuffer( GLcontext *ctx, diff --git a/src/mesa/drivers/dri/i915/intel_pixel.h b/src/mesa/drivers/dri/i915/intel_pixel.h index c24ca08a22e..21c1a3ec000 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.h +++ b/src/mesa/drivers/dri/i915/intel_pixel.h @@ -32,7 +32,11 @@ void intelInitPixelFuncs( struct dd_function_table *functions ); -GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ); +GLboolean intel_check_blit_fragment_ops( const GLcontext *ctx ); + +GLboolean intel_check_blit_format( struct intel_region *region, + GLenum type, GLenum format ); + GLboolean intel_clip_to_framebuffer( GLcontext *ctx, const GLframebuffer *buffer, diff --git a/src/mesa/drivers/dri/i915/intel_pixel_copy.c b/src/mesa/drivers/dri/i915/intel_pixel_copy.c index 8743902dc58..8d2bb4ed568 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_copy.c @@ -173,7 +173,7 @@ static GLboolean do_blit_copypixels( GLcontext *ctx, /* Copypixels can be more than a straight copy. Ensure all the * extra operations are disabled: */ - if (!intel_check_color_per_fragment_ops(ctx) || + if (!intel_check_blit_fragment_ops(ctx) || ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) return GL_FALSE; diff --git a/src/mesa/drivers/dri/i915/intel_pixel_draw.c b/src/mesa/drivers/dri/i915/intel_pixel_draw.c index 081e6ba69da..1aaf3437776 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_draw.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -12,7 +12,7 @@ * the following conditions: * * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions + * next paragraph) shall be included in all copies or substantial portionsalloc * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS @@ -27,8 +27,10 @@ #include "glheader.h" #include "enums.h" +#include "image.h" #include "mtypes.h" #include "macros.h" +#include "bufferobj.h" #include "swrast/swrast.h" #include "intel_screen.h" @@ -38,6 +40,7 @@ #include "intel_blit.h" #include "intel_regions.h" #include "intel_pixel.h" +#include "intel_buffer_objects.h" #include "bufmgr.h" @@ -118,6 +121,12 @@ static GLboolean do_texture_draw_pixels( struct intel_context *intel, * - uploads the whole image even if destination is clipped * * Need to benchmark. + * + * Given the questions about performance, implement for pbo's only. + * This path is definitely a win if the pbo is already in agp. If it + * turns out otherwise, we can add the code necessary to upload client + * data to agp space before performing the blit. (Though it may turn + * out to be better/simpler just to use the texture engine). */ static GLboolean do_blit_draw_pixels( struct intel_context *intel, GLint x, GLint y, @@ -126,17 +135,36 @@ static GLboolean do_blit_draw_pixels( struct intel_context *intel, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { -#if 0 + GLcontext *ctx = &intel->ctx; struct intel_region *dest = intel_drawbuf_region(intel); - struct intel_region *src = NULL; - + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint src_offset; + GLuint src_y = 0; + GLuint rowLength; + GLuint fence; + if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); - if (!src || !dest) + if (!dest) return GL_FALSE; - if (!intel_check_blit_format(dest, src)) + if (src) { + /* This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + return GL_FALSE; + } + + if (!intel_check_blit_format(dest, format, type)) return GL_FALSE; if (!intel_check_blit_fragment_ops(ctx)) @@ -145,30 +173,24 @@ static GLboolean do_blit_draw_pixels( struct intel_context *intel, if (ctx->Pixel.ZoomX != 1.0F) return GL_FALSE; + + + if (unpack->RowLength > 0) + rowLength = unpack->RowLength; + else + rowLength = width; + if (ctx->Pixel.ZoomY == -1.0F) - y -= height; + y -= height; else if (ctx->Pixel.ZoomY == 1.0F) { - src_pitch = -src_pitch; + rowLength = -rowLength; src_y += height; } else return GL_FALSE; - - if (unpack->BufferObj->Name) { - src = intel_bufferobj_unpack_region(intel, unpack, - width, height, - format, type, - unpack->BufferObj); - src_offset = (unsigned long)pixels; - } - else { - src = intel_client_unpack_region(intel, unpack, - width, height, - format, type, pixels); - src_offset = 0; - } - + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); @@ -177,40 +199,43 @@ static GLboolean do_blit_draw_pixels( struct intel_context *intel, int nbox = dPriv->numClipRects; drm_clip_rect_t *box = dPriv->pClipRects; drm_clip_rect_t rect; + drm_clip_rect_t dest_rect; int i; y = dPriv->h - y - height; /* convert from gl to hardware coords */ x += dPriv->x; y += dPriv->y; + dest_rect.x1 = x; + dest_rect.y1 = y; + dest_rect.x2 = x + width; + dest_rect.y2 = y + height; for (i = 0 ; i < nbox ; i++ ) { - if (!intel_intersect_cliprects(rect, db_rect, &box[i])) + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) continue; intelEmitCopyBlit( intel, - intel->intelScreen->cpp, - src->pitch, src->buffer, src_offset, - dst->pitch, dst->buffer, 0, - rect->x1 - x, - rect->y1 - y, - rect->x1, - rect->y1, - rect->x2 - rect->x1, - rect->y2 - rect->y1 ); + dest->cpp, + rowLength * dest->cpp, + intel_bufferobj_buffer(src), src_offset, + dest->pitch, + dest->buffer, 0, + rect.x1 - x, + rect.y1 + src_y - (y * ctx->Pixel.ZoomY), + rect.x1, + rect.y1, + rect.x2 - rect.x1, + rect.y2 - rect.y1 ); } } - intel_release_unpack_region( intel, src ); fence = intel_batchbuffer_flush( intel->batch ); UNLOCK_HARDWARE( intel ); - bmWaitFence(intel->bm, fence); - intel_region_release(intel, &src); -#endif - - return GL_FALSE; + bmFinishFence(intel->bm, fence); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i915/intel_tex_image.c b/src/mesa/drivers/dri/i915/intel_tex_image.c index 01198a00951..d38f20606bb 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915/intel_tex_image.c @@ -305,11 +305,11 @@ static void intelTexImage(GLcontext *ctx, texImage->Data = malloc(sizeInBytes); } - fprintf(stderr, - "Upload image %dx%dx%d row_len %x " - "pitch %x depth_pitch %x\n", - width, height, depth, - width * texelBytes, dstRowStride, dstImageStride); + if (INTEL_DEBUG & DEBUG_TEXTURE) + _mesa_printf("Upload image %dx%dx%d row_len %x " + "pitch %x depth_pitch %x\n", + width, height, depth, + width * texelBytes, dstRowStride, dstImageStride); /* Copy data. Would like to know when it's ok for us to eg. use * the blitter to copy. Or, use the hardware to do the format