Commit b3b325e5 authored by Keith Whitwell's avatar Keith Whitwell

get 3d textures working again

parent 382ce985
......@@ -71,11 +71,9 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
GLuint d = dim;
for (i = mt->first_level; i <= mt->last_level; i++) {
mt->offset[face][i].x = x;
mt->offset[face][i].y = y;
mt->offset[face][i].width = d;
mt->offset[face][i].height = d;
mt->offset[face][i].depth = 1;
intel_miptree_set_image_offset(mt, face, i,
x, y,
d, d, 1);
if (d == 0)
_mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n",
......@@ -93,21 +91,17 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
GLuint height = mt->height0;
GLuint depth = mt->depth0;
/* Calculate the size of a single slice. Hardware demands a
* minimum of 8 mipmaps, some of which might ultimately not be
* used:
/* Calculate the size of a single slice.
*/
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
mt->total_height = 0;
/* XXX: fixme! hardware expects/requires 9 levels at minimum.
/* XXX: hardware expects/requires 9 levels at minimum.
*/
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = 0;
mt->offset[0][i].y = mt->total_height;
mt->offset[0][i].width = width;
mt->offset[0][i].height = height;
mt->offset[0][i].depth = depth;
for ( i = mt->first_level ; i <= MAX2(8, mt->last_level) ; i++ ) {
intel_miptree_set_image_offset(mt, 0, i,
0, mt->total_height,
width, height, depth);
mt->total_height += MAX2(2, height);
......@@ -116,12 +110,17 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
depth = minify(depth);
}
/* Fixup depth_image_stride:
*/
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].depth_image_stride = mt->total_height * mt->pitch * mt->cpp;
}
/* Multiply slice size by texture depth for total size. It's
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
mt->depth_pitch = mt->total_height * mt->pitch;
mt->total_height *= mt->depth0;
break;
}
......@@ -134,13 +133,10 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
mt->total_height = 0;
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = 0;
mt->offset[0][i].y = mt->total_height;
mt->offset[0][i].height = height;
mt->offset[0][i].width = width;
mt->offset[0][i].depth = 1;
intel_miptree_set_image_offset(mt, 0, i,
0, mt->total_height,
width, height, 1);
if (mt->compressed)
mt->total_height += MAX2(1, height/4);
else
......@@ -198,14 +194,11 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
}
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[face][i].x = x;
mt->offset[face][i].y = y;
mt->offset[face][i].width = d;
mt->offset[face][i].height = d;
mt->offset[face][i].depth = 1;
intel_miptree_set_image_offset(mt, face, i,
x, y,
d, d, 1);
d >>= 1;
assert(d > 0);
switch (d) {
case 4:
......@@ -259,11 +252,11 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = 0;
mt->offset[0][i].y = mt->total_height;
mt->offset[0][i].width = width;
mt->offset[0][i].height = height;
mt->offset[0][i].depth = depth;
intel_miptree_set_image_offset(mt, 0, i,
0, mt->total_height,
width, height, depth);
mt->total_height += MAX2(2, height) * MAX2((depth >> depth_packing), 1);
......@@ -273,7 +266,7 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
*/
if (depth_pack_pitch > 4) {
depth_packing++;
depth_pack_pitch <<= 2; /* KW: is this right?? */
depth_pack_pitch >>= 2; /* KW: is this right?? */
}
width = minify(width);
......@@ -298,11 +291,9 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
mt->total_height = 0;
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = x;
mt->offset[0][i].y = y;
mt->offset[0][i].height = height;
mt->offset[0][i].width = width;
mt->offset[0][i].depth = 1;
intel_miptree_set_image_offset(mt, 0, i,
x, y,
width, height, 1);
/* LPT change: step right after second mipmap.
......
......@@ -296,10 +296,10 @@ void i915UpdateTextureState( struct intel_context *intel )
case TEXTURE_1D_BIT:
case TEXTURE_2D_BIT:
case TEXTURE_CUBE_BIT:
case TEXTURE_3D_BIT:
ok = i915_update_tex_unit( intel, i, SS3_NORMALIZED_COORDS );
break;
case TEXTURE_RECT_BIT:
case TEXTURE_3D_BIT:
ok = i915_update_tex_unit( intel, i, 0 );
break;
case 0: {
......
......@@ -51,7 +51,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
{
struct intel_context *intel;
DBG(stderr, "%s\n", __FUNCTION__);
DBG("%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
......
......@@ -177,8 +177,27 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level)
{
return (mt->offset[face][level].x +
mt->offset[face][level].y * mt->pitch) * mt->cpp;
return mt->offset[face][level].offset;
}
GLuint intel_miptree_depth_image_stride(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level)
{
return mt->offset[face][level].depth_image_stride;
}
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint x, GLuint y,
GLuint w, GLuint h, GLuint d)
{
mt->offset[face][level].offset = (x + y * mt->pitch) * mt->cpp;
mt->offset[face][level].width = w;
mt->offset[face][level].height = h;
mt->offset[face][level].depth = d;
}
......@@ -188,12 +207,16 @@ GLubyte *intel_miptree_image_map(struct intel_context *intel,
struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint *stride)
GLuint *row_stride,
GLuint *image_stride)
{
DBG("%s \n", __FUNCTION__);
if (stride)
*stride = mt->pitch * mt->cpp;
if (row_stride)
*row_stride = mt->pitch * mt->cpp;
if (image_stride)
*image_stride = mt->offset[face][level].depth_image_stride;
return (intel_region_map(intel, mt->region) +
intel_miptree_image_offset(mt, face, level));
......@@ -209,25 +232,34 @@ void intel_miptree_image_unmap(struct intel_context *intel,
/* 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 )
void *src,
GLuint src_row_pitch,
GLuint src_image_pitch)
{
GLuint depth = dst->offset[face][level].depth;
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
GLuint dst_image_stride = intel_miptree_depth_image_stride(dst, face, level);
GLuint i;
DBG("%s\n", __FUNCTION__);
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);
for (i = 0; i < depth; i++) {
intel_region_data(intel,
dst->region, dst_offset,
0,
0,
src,
src_row_pitch,
0, 0, /* source x,y */
dst->offset[face][level].width,
dst->offset[face][level].height);
dst_offset += dst_image_stride;
src += src_image_pitch;
}
}
/* Copy mipmap image between trees
......@@ -237,21 +269,28 @@ void intel_miptree_image_copy( struct intel_context *intel,
GLuint face, GLuint level,
struct intel_mipmap_tree *src )
{
DBG("%s\n", __FUNCTION__);
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);
GLuint width = src->offset[face][level].width;
GLuint height = src->offset[face][level].height;
GLuint depth = src->offset[face][level].depth;
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
GLuint src_offset = intel_miptree_image_offset(src, face, level);
GLuint dst_image_stride = intel_miptree_depth_image_stride(dst, face, level);
GLuint src_image_stride = intel_miptree_depth_image_stride(src, face, level);
GLuint i;
for (i = 0; i < depth; i++) {
intel_region_copy(intel,
dst->region, dst_offset,
0,
0,
src->region, src_offset,
0,
0,
width,
height);
dst_offset += dst_image_stride;
src_offset += src_image_stride;
}
}
......@@ -58,11 +58,11 @@
struct intel_mipmap_offset {
GLuint x;
GLuint y;
GLuint offset;
GLuint width;
GLuint height;
GLuint depth; /* how will this work? */
GLuint depth;
GLuint depth_image_stride;
};
struct intel_mipmap_tree {
......@@ -127,7 +127,8 @@ GLubyte *intel_miptree_image_map( struct intel_context *intel,
struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint *stride );
GLuint *row_stride,
GLuint *image_stride);
void intel_miptree_image_unmap( struct intel_context *intel,
struct intel_mipmap_tree *mt );
......@@ -140,6 +141,16 @@ GLuint intel_miptree_image_offset( struct intel_mipmap_tree *mt,
GLuint face,
GLuint level );
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint x, GLuint y,
GLuint w, GLuint h, GLuint d);
GLuint intel_miptree_depth_image_stride(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level);
/* Upload an image into a tree
......@@ -148,7 +159,9 @@ void intel_miptree_image_data(struct intel_context *intel,
struct intel_mipmap_tree *dst,
GLuint face,
GLuint level,
void *src, GLuint src_pitch );
void *src,
GLuint src_row_pitch,
GLuint src_image_pitch);
/* Copy an image between two trees
*/
......
......@@ -197,6 +197,7 @@ static void _mesa_copy_rect( GLubyte *dst,
*/
void intel_region_data(struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
void *src, GLuint src_pitch,
GLuint srcx, GLuint srcy,
......@@ -206,7 +207,7 @@ void intel_region_data(struct intel_context *intel,
LOCK_HARDWARE(intel);
_mesa_copy_rect(intel_region_map(intel, dst),
_mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
dst->cpp,
dst->pitch,
dstx, dsty,
......@@ -226,8 +227,10 @@ void intel_region_data(struct intel_context *intel,
*/
void intel_region_copy( struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
struct intel_region *src,
GLuint src_offset,
GLuint srcx, GLuint srcy,
GLuint width, GLuint height )
{
......@@ -237,8 +240,8 @@ void intel_region_copy( struct intel_context *intel,
intelEmitCopyBlit(intel,
dst->cpp,
src->pitch, src->buffer, 0,
dst->pitch, dst->buffer, 0,
src->pitch, src->buffer, src_offset,
dst->pitch, dst->buffer, dst_offset,
srcx, srcy,
dstx, dsty,
width, height);
......@@ -249,6 +252,7 @@ void intel_region_copy( struct intel_context *intel,
*/
void intel_region_fill( struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
GLuint width, GLuint height,
GLuint color )
......@@ -257,9 +261,7 @@ void intel_region_fill( struct intel_context *intel,
intelEmitFillBlit(intel,
dst->cpp,
dst->pitch,
dst->buffer,
0,
dst->pitch, dst->buffer, dst_offset,
dstx, dsty,
width, height,
color );
......
......@@ -85,6 +85,7 @@ void intel_region_unmap(struct intel_context *intel,
*/
void intel_region_data(struct intel_context *intel,
struct intel_region *dest,
GLuint dest_offset,
GLuint destx, GLuint desty,
void *src, GLuint src_stride,
GLuint srcx, GLuint srcy,
......@@ -94,8 +95,10 @@ void intel_region_data(struct intel_context *intel,
*/
void intel_region_copy( struct intel_context *intel,
struct intel_region *dest,
GLuint dest_offset,
GLuint destx, GLuint desty,
struct intel_region *src,
GLuint src_offset,
GLuint srcx, GLuint srcy,
GLuint width, GLuint height );
......@@ -103,6 +106,7 @@ void intel_region_copy( struct intel_context *intel,
*/
void intel_region_fill( struct intel_context *intel,
struct intel_region *dest,
GLuint dest_offset,
GLuint destx, GLuint desty,
GLuint width, GLuint height,
GLuint color );
......
......@@ -140,8 +140,10 @@ void intelInitTextureFuncs(struct dd_function_table * functions)
functions->ChooseTextureFormat = intelChooseTextureFormat;
functions->TexImage1D = intelTexImage1D;
functions->TexImage2D = intelTexImage2D;
functions->TexImage3D = intelTexImage3D;
functions->TexSubImage1D = intelTexSubImage1D;
functions->TexSubImage2D = intelTexSubImage2D;
functions->TexSubImage3D = intelTexSubImage3D;
functions->CopyTexImage1D = intelCopyTexImage1D;
functions->CopyTexImage2D = intelCopyTexImage2D;
functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
......
......@@ -39,6 +39,28 @@ const struct gl_texture_format *
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type );
void intelTexImage3D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint depth,
GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage);
void intelTexSubImage3D(GLcontext *ctx,
GLenum target,
GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage);
void intelTexImage2D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
......
......@@ -151,7 +151,8 @@ static void intelTexImage(GLcontext *ctx,
GLint dims,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint border,
GLint width, GLint height, GLint depth,
GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
......@@ -164,12 +165,13 @@ static void intelTexImage(GLcontext *ctx,
GLint postConvHeight = height;
GLint texelBytes, sizeInBytes;
GLuint dstRowStride;
GLuint dstImageStride;
DBG("%s target %s level %d %dx%d border %d\n", __FUNCTION__,
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
level,
width, height, border);
width, height, depth, border);
intelFlush(ctx);
......@@ -187,14 +189,24 @@ static void intelTexImage(GLcontext *ctx,
assert(texImage->TexFormat);
if (dims == 1) {
switch (dims) {
case 1:
texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
}
else {
break;
case 2:
texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
break;
case 3:
texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
break;
default:
assert(0);
break;
}
texelBytes = texImage->TexFormat->TexelBytes;
......@@ -220,19 +232,7 @@ static void intelTexImage(GLcontext *ctx,
/* If this is the only texture image in the tree, could call
* bmBufferData with NULL data to free the old block and avoid
* waiting on any outstanding fences.
*
* XXX: this hits a malloc/free problem. fixme.
*/
#if 0
if (intelObj->mt &&
intelObj->mt->first_level == level &&
intelObj->mt->last_level == level &&
intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB) {
DBG("release it 2\n");
intel_miptree_release(intel, &intelObj->mt);
}
#endif
if (intelObj->mt &&
intelObj->mt->first_level == level &&
intelObj->mt->last_level == level &&
......@@ -286,20 +286,30 @@ static void intelTexImage(GLcontext *ctx,
intelImage->mt,
intelImage->face,
intelImage->level,
&dstRowStride);
&dstRowStride,
&dstImageStride);
}
else {
/* Allocate regular memory and store the image there temporarily. */
if (texImage->IsCompressed) {
sizeInBytes = texImage->CompressedSize;
dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,width);
dstImageStride = 0; /* ? */
assert(dims != 3);
}
else {
sizeInBytes = postConvWidth * postConvHeight * texelBytes;
dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
dstRowStride = postConvWidth * texelBytes;
dstImageStride = dstRowStride * postConvHeight;
sizeInBytes = depth * dstImageStride;
}
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);
/* 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
......@@ -310,8 +320,8 @@ static void intelTexImage(GLcontext *ctx,
texImage->TexFormat,
texImage->Data,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride, 0 /* dstImageStride */,
width, height, 1,
dstRowStride, dstImageStride,
width, height, depth,
format, type, pixels, unpack)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
}
......@@ -337,6 +347,22 @@ static void intelTexImage(GLcontext *ctx,
#endif
}
void intelTexImage3D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint depth,
GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intelTexImage( ctx, 3, target, level,
internalFormat, width, height, depth, border,
format, type, pixels,
unpack, texObj, texImage );
}
void intelTexImage2D(GLcontext *ctx,
GLenum target, GLint level,
......@@ -348,9 +374,9 @@ void intelTexImage2D(GLcontext *ctx,
struct gl_texture_image *texImage)
{
intelTexImage( ctx, 2, target, level,
internalFormat, width, height, border,
format, type, pixels,
unpack, texObj, texImage );
internalFormat, width, height, 1, border,
format, type, pixels,
unpack, texObj, texImage );
}
void intelTexImage1D(GLcontext *ctx,
......@@ -363,7 +389,7 @@ void intelTexImage1D(GLcontext *ctx,
struct gl_texture_image *texImage)
{
intelTexImage( ctx, 1, target, level,
internalFormat, width, 1, border,
internalFormat, width, 1, 1, border,
format, type, pixels,
unpack, texObj, texImage );
}
......
......@@ -39,8 +39,8 @@
static void intelTexSubimage (GLcontext *ctx,
GLint dims,
GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint width, GLint height,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
......@@ -48,7 +48,7 @@ static void intelTexSubimage (GLcontext *ctx,
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
GLuint dstImageStride = 0;
GLuint dstImageStride;
GLuint dstRowStride;
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
......@@ -59,7 +59,7 @@ static void intelTexSubimage (GLcontext *ctx,
intelFlush(ctx);
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type,
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, type,
pixels, packing, "glTexSubImage2D");
if (!pixels)
return;
......@@ -74,18 +74,19 @@ static void intelTexSubimage (GLcontext *ctx,
intelImage->mt,
intelImage->face,
intelImage->level,
&dstRowStride );
&dstRowStride,
&dstImageStride );
assert(dstRowStride);
if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
xoffset, yoffset, 0,
xoffset, yoffset, zoffset,
dstRowStride, dstImageStride,
width, height, 1,
width, height, depth,
format, type, pixels, packing)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
_mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
}
#if 0
......@@ -111,6 +112,28 @@ static void intelTexSubimage (GLcontext *ctx,
void intelTexSubImage3D(GLcontext *ctx,
GLenum target,
GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intelTexSubimage(ctx, 3,
target, level,
xoffset, yoffset, zoffset,
width, height, depth,
format, type, pixels, packing, texObj,
texImage);
}