Not yet working.tags/texman_0_1_20060325
| @@ -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 \ | |||
| @@ -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); | |||
| /* XXX: do something useful with 'usage' (eg. populate flags | |||
| * argument below) | |||
| */ | |||
| bmBufferData(intel->bm, obj->buffer, size, data, 0); | |||
| } | |||
| 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) | |||
| */ | |||
| 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); | |||
| /* XXX: Translate access to flags arg below: | |||
| */ | |||
| return bmMapBuffer(intel->bm, intel_obj->buffer, 0); | |||
| } | |||
| return NULL; | |||
| struct intel_context *intel = intel_context(ctx); | |||
| struct intel_buffer_object *intel_obj = intel_buffer_object(obj); | |||
| /* 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; | |||
| } | |||
| @@ -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 | |||
| @@ -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; | |||
| @@ -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, | |||
| @@ -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, | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||