diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2006-01-24 16:38:43 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2006-01-24 16:38:43 +0000 |
commit | 3bca9c47f473f603e9da97797a866ddac62d0cba (patch) | |
tree | 98c30eb91728e3cc68446e9620224681045843ed | |
parent | d4d7fdb43ba9a0b15b66ffdcf9b1ed9d86ff8014 (diff) |
Add another layer on top of the simple 2d regions in intel_regions.[ch]
which keeps track of a whole, well-defined mipmap tree. These are a
fixed layout on intel hardware and managing them is complicated in the
face of GL's TexImage function calls where data can arrive in any order,
making it difficult to guess a layout ahead of time.
Wrapping mipmap trees up in a struct and programming interface like this
reduces the burden elsewhere.
-rw-r--r-- | src/mesa/drivers/dri/i915/bufmgr.h | 33 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/bufmgr_fake.c | 76 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_mipmap_tree.c | 218 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_mipmap_tree.h | 156 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_regions.c | 101 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_regions.h | 4 |
6 files changed, 489 insertions, 99 deletions
diff --git a/src/mesa/drivers/dri/i915/bufmgr.h b/src/mesa/drivers/dri/i915/bufmgr.h index c0849d4adac..c999a4ca4c6 100644 --- a/src/mesa/drivers/dri/i915/bufmgr.h +++ b/src/mesa/drivers/dri/i915/bufmgr.h @@ -10,6 +10,7 @@ /* The buffer manager context. Opaque. */ struct bufmgr; +struct bm_buffer_list; struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); @@ -23,18 +24,13 @@ void bmInitPool( struct bufmgr *, unsigned long high_offset, void *virtual_base ); - -#define BM_MEM_SYS 0x1 +#define BM_MEM_LOCAL 0x1 #define BM_MEM_AGP 0x2 #define BM_MEM_VRAM 0x4 /* not used */ #define BM_WRITE 0x100 /* not used */ #define BM_READ 0x200 /* not used */ -/* Maximum number of buffers to pass to bmValidateBufferList: - */ -#define BM_VALIDATE_MAX 32 - /* Flags for validate. If both NO_UPLOAD and NO_EVICT are specified, * ValidateBuffers is essentially a query. @@ -76,34 +72,39 @@ void bmUnmapBuffer( struct bufmgr *, /* To be called prior to emitting commands to hardware which reference * these buffers. * - * ClearBufferList() and AddBuffer() build up a list of buffers to be + * NewBufferList() and AddBuffer() build up a list of buffers to be * validated. The buffer list provides information on where the * buffers should be placed and whether their contents need to be * preserved on copying. The offset data elements are return values * from this function telling the driver exactly where the buffers are * currently located. * - * ValidateBuffers() performs the actual validation. + * ValidateBufferList() performs the actual validation and returns the + * buffer pools and offsets within the pools. * - * ReleaseValidatedBuffers() must be called to set fences and other + * FenceBufferList() must be called to set fences and other * housekeeping before unlocking after a successful call to - * ValidateBuffers(). - * - * The buffer manager knows how to emit and test fences directly - * through the drm and without callbacks or whatever into the driver. + * ValidateBufferList(). The buffer manager knows how to emit and test + * fences directly through the drm and without callbacks to the + * driver. */ -void bmClearBufferList( struct bufmgr * ); +struct bm_buffer_list *bmNewBufferList( void ); -void bmAddBuffer( struct bufmgr *bm, +void bmAddBuffer( struct bufmgr *, + struct bm_buffer_list *list, unsigned buffer, unsigned flags, unsigned *pool_return, unsigned *offset_return ); int bmValidateBufferList( struct bufmgr *, + struct bm_buffer_list *, unsigned flags ); -void bmReleaseValidatedBuffers( struct bufmgr * ); +void bmFenceBufferList( struct bufmgr *, + struct bm_buffer_list * ); + +void bmFreeBufferList( struct bm_buffer_list * ); /* This functionality is used by the buffer manager, not really sure diff --git a/src/mesa/drivers/dri/i915/bufmgr_fake.c b/src/mesa/drivers/dri/i915/bufmgr_fake.c index 574f632983c..7e498a8afd5 100644 --- a/src/mesa/drivers/dri/i915/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i915/bufmgr_fake.c @@ -18,8 +18,11 @@ struct _mesa_HashTable; -#define BM_MEM_LOCAL 0x1 -#define BM_MEM_AGP 0x2 + +/* Maximum number of buffers to pass to bmValidateBufferList: + */ +#define BM_LIST_MAX 32 + /* Wrapper around mm.c's mem_block, which understands that you must * wait for fences to expire before memory can be freed. This is @@ -53,6 +56,16 @@ struct pool { struct block freed; }; +/* List of buffers to validate: + */ +struct bm_buffer_list { + struct buffer *buffer[BM_LIST_MAX]; + unsigned *offset_return[BM_LIST_MAX]; + unsigned nr; + unsigned need_fence; +}; + + struct bufmgr { struct intel_context *intel; struct buffer buffer_list; @@ -61,14 +74,7 @@ struct bufmgr { unsigned buf_nr; /* for generating ids */ - /* List of buffers to validate: - */ - struct buffer *validated[BM_VALIDATE_MAX]; - unsigned *offset_return[BM_VALIDATE_MAX]; - unsigned nr_validated; - unsigned last_fence; - unsigned in_progress; }; @@ -194,7 +200,7 @@ static int move_buffers( struct bufmgr *bm, int newMemType, int flags ) { - struct block *newMem[BM_VALIDATE_MAX]; + struct block *newMem[BM_LIST_MAX]; GLint i; memset(newMem, 0, sizeof(newMem)); @@ -476,28 +482,34 @@ void bm_fake_SetFixedBufferParams( struct bufmgr *bm /* Build the list of buffers to validate: */ -void bmClearBufferList( struct bufmgr *bm ) +struct bm_buffer_list *bmNewBufferList( void ) { - assert(!bm->in_progress); - bm->nr_validated = 0; + struct bm_buffer_list *list = calloc(sizeof(*list), 1); + return list; } void bmAddBuffer( struct bufmgr *bm, + struct bm_buffer_list *list, unsigned buffer, unsigned flags, unsigned *pool_return, unsigned *offset_return ) { - assert(bm->nr_validated < BM_VALIDATE_MAX); + assert(list->nr < BM_LIST_MAX); - bm->validated[bm->nr_validated] = _mesa_HashLookup(bm->hash, buffer); - bm->offset_return[bm->nr_validated] = offset_return; - bm->nr_validated++; + list->buffer[list->nr] = _mesa_HashLookup(bm->hash, buffer); + list->offset_return[list->nr] = offset_return; + list->nr++; if (pool_return) *pool_return = 0; } - + +void bmFreeBufferList( struct bm_buffer_list *list ) +{ + assert(!list->need_fence); + free(list); +} @@ -510,17 +522,18 @@ void bmAddBuffer( struct bufmgr *bm, * buffers are currently located. */ int bmValidateBufferList( struct bufmgr *bm, + struct bm_buffer_list *list, unsigned flags ) { unsigned i; unsigned total = 0; - if (bm->nr_validated > BM_VALIDATE_MAX) + if (list->nr > BM_LIST_MAX) return 0; - for (i = 0; i < bm->nr_validated; i++) { - assert(!bm->validated[i]->mapped); - total += bm->validated[i]->size; + for (i = 0; i < list->nr; i++) { + assert(!list->buffer[i]->mapped); + total += list->buffer[i]->size; } /* Don't need to try allocation in this case: @@ -532,13 +545,13 @@ int bmValidateBufferList( struct bufmgr *bm, * succeeds. This is a pretty poor strategy but really hard to do * better without more infrastucture... Which is coming - hooray! */ - while (!move_buffers(bm, bm->validated, bm->nr_validated, BM_MEM_AGP, flags)) { + while (!move_buffers(bm, list->buffer, list->nr, BM_MEM_AGP, flags)) { if ((flags & BM_NO_EVICT) || !evict_lru(bm)) return 0; } - bm->in_progress = 1; + list->need_fence = 1; return 1; } @@ -551,20 +564,21 @@ int bmValidateBufferList( struct bufmgr *bm, * The buffer manager knows how to emit and test fences directly * through the drm and without callbacks or whatever into the driver. */ -void bmReleaseValidatedBuffers( struct bufmgr *bm ) +void bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list ) { unsigned i; - assert(bm->in_progress); - bm->in_progress = 0; + assert(list->need_fence); + list->need_fence = 0; + bm->last_fence = bmSetFence( bm ); /* Move all buffers to head of resident list and set their fences */ - for (i = 0; i < bm->nr_validated; i++) { - assert(bm->validated[i]->block->buf == bm->validated[i]); - move_to_head(&bm->pool.lru, bm->validated[i]->block); - bm->validated[i]->block->fence = bm->last_fence; + for (i = 0; i < list->nr; i++) { + assert(list->buffer[i]->block->buf == list->buffer[i]); + move_to_head(&bm->pool.lru, list->buffer[i]->block); + list->buffer[i]->block->fence = bm->last_fence; } } diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c new file mode 100644 index 00000000000..72bc25fa529 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c @@ -0,0 +1,218 @@ +/************************************************************************** + * + * 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 portions + * 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 "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "bufmgr.h" + +static GLenum target_to_target( GLenum target ) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return GL_TEXTURE_CUBE_MAP_ARB; + default: + return target; + } +} + +struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint cpp, + GLboolean compressed) +{ + GLboolean ok; + struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); + + mt->target = target_to_target(target); + mt->internal_format = internal_format; + mt->first_level = first_level; + mt->last_level = last_level; + mt->width0 = width0; + mt->height0 = height0; + mt->depth0 = depth0; + mt->cpp = cpp; + mt->compressed = compressed; + + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + ok = i945_miptree_layout( mt ); + break; + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + ok = i915_miptree_layout( mt ); + break; + default: + ok = 0; + break; + } + + if (ok) + mt->region = intel_region_alloc( intel, + mt->cpp, + mt->pitch, + mt->total_height ); + + if (!mt->region) { + free(mt); + return NULL; + } + + return mt; +} + + +struct intel_mipmap_tree *intel_miptree_reference( struct intel_mipmap_tree *mt ) +{ + mt->refcount++; + return mt; +} + +void intel_miptree_release( struct intel_context *intel, + struct intel_mipmap_tree *mt ) +{ + if (--mt->refcount) { + intel_region_release(intel, mt->region); + free(mt); + } +} + + + + +/* Can the image be pulled into a unified mipmap tree. This mirrors + * the completeness test in a lot of ways. + * + * Not sure whether I want to pass gl_texture_image here. + */ +GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, + GLuint level ) +{ + /* Images with borders are never pulled into mipmap trees. + */ + if (image->Border) + return GL_FALSE; + + if (image->InternalFormat != mt->internal_format || + image->IsCompressed != mt->compressed) + return GL_FALSE; + + /* Test image dimensions against the base level image adjusted for + * minification. This will also catch images not present in the + * tree, changed targets, etc. + */ + if (image->Width != mt->offset[face][level].width || + image->Height != mt->offset[face][level].height || + image->Depth != mt->offset[face][level].depth) + return GL_FALSE; + + return GL_TRUE; +} + + +GLubyte *intel_miptree_image_map(struct intel_context *intel, + struct intel_mipmap_tree *mt, + GLuint face, + GLuint level, + GLuint *stride) +{ + GLubyte *img = intel_region_map(intel, mt->region); + + if (stride) + *stride = mt->pitch * mt->cpp; + + return img + (mt->offset[face][level].x + + mt->offset[face][level].y * mt->pitch) * mt->cpp; +} + +void intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt) +{ + intel_region_unmap(intel, mt->region); +} + + + + +/* Upload data for a particular image. + * + * TODO: 3D textures + */ +void intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, GLuint src_pitch ) +{ + intel_region_data(intel, + dst->region, + dst->offset[face][level].x, + dst->offset[face][level].y, + src, + src_pitch, + 0, 0, /* source x,y */ + dst->offset[face][level].width, + dst->offset[face][level].height); +} + +/* Copy mipmap image between trees + */ +void intel_miptree_image_copy( struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src ) +{ + assert(src->offset[face][level].width == + dst->offset[face][level].width); + + assert(src->offset[face][level].height == + dst->offset[face][level].height); + + intel_region_copy(intel, + dst->region, + dst->offset[face][level].x, + dst->offset[face][level].y, + src->region, + src->offset[face][level].x, + src->offset[face][level].y, + src->offset[face][level].width, + src->offset[face][level].height); + +} diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h new file mode 100644 index 00000000000..2064f65bad1 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h @@ -0,0 +1,156 @@ +/************************************************************************** + * + * 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 portions + * 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. + * + **************************************************************************/ + +#ifndef INTEL_MIPMAP_TREE_H +#define INTEL_MIPMAP_TREE_H + +#include "intel_regions.h" + +/* A layer on top of the intel_regions code which adds: + * + * - Code to size and layout a region to hold a set of mipmaps. + * - Query to determine if a new image fits in an existing tree. + * - More refcounting + * - maybe able to remove refcounting from intel_region? + * - ? + * + * The fixed mipmap layout of intel hardware where one offset + * specifies the position of all images in a mipmap hierachy + * complicates the implementation of GL texture image commands, + * compared to hardware where each image is specified with an + * independent offset. + * + * In an ideal world, each texture object would be associated with a + * single bufmgr buffer or 2d intel_region, and all the images within + * the texture object would slot into the tree as they arrive. The + * reality can be a little messier, as images can arrive from the user + * with sizes that don't fit in the existing tree, or in an order + * where the tree layout cannot be guessed immediately. + * + * This structure encodes an idealized mipmap tree. The GL image + * commands build these where possible, otherwise store the images in + * temporary system buffers. + */ + + +struct intel_mipmap_offset { + GLuint x; + GLuint y; + GLuint width; + GLuint height; + GLuint depth; /* how will this work? */ +}; + +struct intel_mipmap_tree { + /* Effectively the key: + */ + GLenum target; + GLenum internal_format; + + GLuint first_level; + GLuint last_level; + + GLuint width0, height0, depth0; + GLuint cpp; + GLboolean compressed; + + /* Derived from the above: + */ + GLuint pitch; + GLuint depth_pitch; /* per-image on i945? */ + GLuint total_height; + struct intel_mipmap_offset offset[MAX_FACES][MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct intel_region *region; + + /* These are also refcounted: + */ + GLuint refcount; +}; + + + +struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint cpp, + GLboolean compressed); + +struct intel_mipmap_tree *intel_miptree_reference( struct intel_mipmap_tree * ); + +void intel_miptree_release( struct intel_context *intel, + struct intel_mipmap_tree *mt ); + +/* Check if an image fits an existing mipmap tree layout + */ +GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, + GLuint level ); + +/* Return a pointer to an image within a tree. Return image stride as + * well. + */ +GLubyte *intel_miptree_image_map( struct intel_context *intel, + struct intel_mipmap_tree *mt, + GLuint face, + GLuint level, + GLuint *stride ); + +void intel_miptree_image_unmap( struct intel_context *intel, + struct intel_mipmap_tree *mt ); + +/* Upload an image into a tree + */ +void intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, GLuint src_pitch ); + +/* Copy an image between two trees + */ +void intel_miptree_image_copy( struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src ); + +/* i915_mipmap_tree.c: + */ +GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ); +GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt ); + + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c index 0a84af7f643..a90795d82f0 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.c +++ b/src/mesa/drivers/dri/i915/intel_regions.c @@ -106,9 +106,9 @@ static void _mesa_copy_rect( GLubyte *dst, GLuint width, GLuint height, GLubyte *src, + GLuint src_pitch, GLuint src_x, - GLuint src_y, - GLuint src_pitch ) + GLuint src_y ) { GLuint i; @@ -195,24 +195,24 @@ static void _mesa_fill_rect( GLubyte *dst, * Currently always memcpy. */ void intel_region_data(struct intel_context *intel, - struct intel_region *dest, - GLuint destx, GLuint desty, + struct intel_region *dst, + GLuint dstx, GLuint dsty, void *src, GLuint src_pitch, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { LOCK_HARDWARE(intel); - _mesa_copy_rect(intel_region_map(intel, dest), - dest->cpp, - dest->pitch, - destx, desty, - destx + width, desty + height, + _mesa_copy_rect(intel_region_map(intel, dst), + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, src, - srcx, srcy, - src_pitch); + src_pitch, + srcx, srcy); - intel_region_unmap(intel, dest); + intel_region_unmap(intel, dst); UNLOCK_HARDWARE(intel); @@ -222,52 +222,51 @@ void intel_region_data(struct intel_context *intel, * push buffers into AGP - will currently do so whenever possible. */ void intel_region_copy( struct intel_context *intel, - struct intel_region *dest, - GLuint destx, GLuint desty, + struct intel_region *dst, + GLuint dstx, GLuint dsty, struct intel_region *src, GLuint srcx, GLuint srcy, GLuint width, GLuint height ) { unsigned dst_offset; unsigned src_offset; + struct bm_buffer_list *list = bmNewBufferList(); - assert(src->cpp == dest->cpp); + assert(src->cpp == dst->cpp); LOCK_HARDWARE(intel); - bmClearBufferList(intel->bm); - bmAddBuffer(intel->bm, dest->buffer, BM_WRITE, NULL, &dst_offset); - bmAddBuffer(intel->bm, src->buffer, BM_READ, NULL, &src_offset); + bmAddBuffer(intel->bm, list, dst->buffer, BM_WRITE, NULL, &dst_offset); + bmAddBuffer(intel->bm, list, src->buffer, BM_READ, NULL, &src_offset); /* What I really want to do is query if both buffers are already * uploaded: */ - if (bmValidateBufferList(intel->bm, BM_NO_EVICT|BM_NO_UPLOAD)) { + if (bmValidateBufferList(intel->bm, list, BM_NO_EVICT|BM_NO_UPLOAD)) { intelEmitCopyBlitLocked(intel, - dest->cpp, - src->pitch, - src_offset, - dest->pitch, - dst_offset, - srcx, srcy, - destx, desty, - width, height); - - bmReleaseValidatedBuffers(intel->bm); + dst->cpp, + src->pitch, src_offset, + dst->pitch, dst_offset, + srcx, srcy, + dstx, dsty, + width, height); + + bmFenceBufferList(intel->bm, list); } else { - _mesa_copy_rect(intel_region_map(intel, dest), - dest->cpp, - dest->pitch, - destx, desty, + _mesa_copy_rect(intel_region_map(intel, dst), + dst->cpp, + dst->pitch, + dstx, dsty, width, height, intel_region_map(intel, src), srcx, srcy, src->pitch); - intel_region_unmap(intel, dest); + intel_region_unmap(intel, dst); intel_region_unmap(intel, src); } + bmFreeBufferList(list); UNLOCK_HARDWARE(intel); } @@ -275,40 +274,40 @@ void intel_region_copy( struct intel_context *intel, * push buffers into AGP - will currently do so whenever possible. */ void intel_region_fill( struct intel_context *intel, - struct intel_region *dest, - GLuint destx, GLuint desty, + struct intel_region *dst, + GLuint dstx, GLuint dsty, GLuint width, GLuint height, GLuint color ) { unsigned dst_offset; - LOCK_HARDWARE(intel); + struct bm_buffer_list *list = bmNewBufferList(); - bmClearBufferList(intel->bm); - bmAddBuffer(intel->bm, dest->buffer, BM_WRITE, NULL, &dst_offset); + LOCK_HARDWARE(intel); + bmAddBuffer(intel->bm, list, dst->buffer, BM_WRITE, NULL, &dst_offset); - if (bmValidateBufferList(intel->bm, BM_NO_EVICT)) { + if (bmValidateBufferList(intel->bm, list, BM_NO_EVICT)) { intelEmitFillBlitLocked(intel, - dest->cpp, - dest->pitch, + dst->cpp, + dst->pitch, dst_offset, - destx, desty, + dstx, dsty, width, height, color ); - bmReleaseValidatedBuffers(intel->bm); + bmFenceBufferList(intel->bm, list); } else { - _mesa_fill_rect(intel_region_map(intel, dest), - dest->cpp, - dest->pitch, - destx, desty, - destx + width, desty + height, + _mesa_fill_rect(intel_region_map(intel, dst), + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, color); - intel_region_unmap(intel, dest); + intel_region_unmap(intel, dst); } + bmFreeBufferList(list); UNLOCK_HARDWARE(intel); - } diff --git a/src/mesa/drivers/dri/i915/intel_regions.h b/src/mesa/drivers/dri/i915/intel_regions.h index 581c06a77a9..557facb9ab4 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.h +++ b/src/mesa/drivers/dri/i915/intel_regions.h @@ -28,6 +28,9 @@ #ifndef INTEL_REGIONS_H #define INTEL_REGIONS_H +#include "mtypes.h" + +struct intel_context; /* A layer on top of the bufmgr buffers that adds a few useful things: * @@ -36,7 +39,6 @@ * - Buffer dimensions - pitch and height. * - Blitter commands for copying 2D regions between buffers. */ - struct intel_region { GLuint buffer; GLuint refcount; |