diff options
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r-- | src/mesa/swrast/s_context.h | 10 | ||||
-rw-r--r-- | src/mesa/swrast/s_texture.c | 58 |
2 files changed, 56 insertions, 12 deletions
diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 38015483597..2525e8e2d38 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -148,8 +148,14 @@ struct swrast_texture_image * between all slices. */ GLint RowStride; - void **ImageSlices; /**< if 3D texture: array [Depth] of offsets to - each 2D slice in 'Data', in texels */ + /** + * When a texture image is mapped for swrast, this array contains pointers + * to the beginning of each slice. + * + * For swrast-allocated textures, these pointers will always stay + * initialized to point within Buffer. + */ + void **ImageSlices; GLubyte *Map; /**< Pointer to mapped image memory */ /** Malloc'd texture memory */ diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index 1783d9c477f..27803c55330 100644 --- a/src/mesa/swrast/s_texture.c +++ b/src/mesa/swrast/s_texture.c @@ -266,12 +266,42 @@ _swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj) for (face = 0; face < faces; face++) { for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) { struct gl_texture_image *texImage = texObj->Image[face][level]; - if (texImage) { - struct swrast_texture_image *swImage = - swrast_texture_image(texImage); + struct swrast_texture_image *swImage = swrast_texture_image(texImage); + unsigned int i; + + if (!texImage) + continue; + + /* In the case of a swrast-allocated texture buffer, the ImageSlices + * and RowStride are always available. + */ + if (swImage->Buffer) { + assert(swImage->ImageSlices[0] == swImage->Buffer); + continue; + } - /* XXX we'll eventually call _swrast_map_teximage() here */ - swImage->Map = swImage->Buffer; + for (i = 0; i < texture_slices(texImage); i++) { + GLubyte *map; + GLint rowStride; + + if (swImage->ImageSlices[i]) + continue; + + ctx->Driver.MapTextureImage(ctx, texImage, i, + 0, 0, + texImage->Width, texImage->Height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &map, &rowStride); + + swImage->ImageSlices[i] = map; + /* A swrast-using driver has to return the same rowstride for + * every slice of the same texture, since we don't track them + * separately. + */ + if (i == 0) + swImage->RowStride = rowStride; + else + assert(swImage->RowStride == rowStride); } } } @@ -287,12 +317,20 @@ _swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj) for (face = 0; face < faces; face++) { for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) { struct gl_texture_image *texImage = texObj->Image[face][level]; - if (texImage) { - struct swrast_texture_image *swImage - = swrast_texture_image(texImage); + struct swrast_texture_image *swImage = swrast_texture_image(texImage); + unsigned int i; + + if (!texImage) + continue; + + if (swImage->Buffer) + return; - /* XXX we'll eventually call _swrast_unmap_teximage() here */ - swImage->Map = NULL; + for (i = 0; i < texture_slices(texImage); i++) { + if (swImage->ImageSlices[i]) { + ctx->Driver.UnmapTextureImage(ctx, texImage, i); + swImage->ImageSlices[i] = NULL; + } } } } |