From cfe9e66f2bc596c43760911e7c1604bb32cdee28 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 11 Feb 2008 09:35:28 -0700 Subject: gallium: use _mesa_tex_target_to_face() --- src/mesa/state_tracker/st_cb_texture.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 3350254654..992723afba 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -379,26 +379,6 @@ guess_and_alloc_texture(struct st_context *st, } - - -static GLuint -target_to_face(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 ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); - default: - return 0; - } -} - - - /* There are actually quite a few combinations this will work for, * more than what I've listed here. */ @@ -512,7 +492,7 @@ st_TexImage(GLcontext * ctx, DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); - stImage->face = target_to_face(target); + stImage->face = _mesa_tex_target_to_face(target); stImage->level = level; if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { -- cgit v1.2.3 From 212b27d33f94eeb25ba9cbc58f9e41295a29d2c9 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 11 Feb 2008 09:38:36 -0700 Subject: gallium: strip borders from textures passed to st_TexImage. Manipulate the unpack params to skip the border. Gallium drivers won't support texture borders. --- src/mesa/state_tracker/st_cb_texture.c | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 992723afba..7099ec33b9 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -467,6 +467,43 @@ try_pbo_upload(GLcontext *ctx, } +/** + * Adjust pixel unpack params and image dimensions to strip off the + * texture border. + * Gallium doesn't support texture borders. They've seldem been used + * and seldom been implemented correctly anyway. + * \param unpackNew returns the new pixel unpack parameters + */ +static void +strip_texture_border(GLint border, + GLint *width, GLint *height, GLint *depth, + const struct gl_pixelstore_attrib *unpack, + struct gl_pixelstore_attrib *unpackNew) +{ + assert(border > 0); /* sanity check */ + + *unpackNew = *unpack; + + if (unpackNew->RowLength == 0) + unpackNew->RowLength = *width; + + if (depth && unpackNew->ImageHeight == 0) + unpackNew->ImageHeight = *height; + + unpackNew->SkipPixels += border; + if (height) + unpackNew->SkipRows += border; + if (depth) + unpackNew->SkipImages += border; + + assert(*width >= 3); + *width = *width - 2 * border; + if (height && *height >= 3) + *height = *height - 2 * border; + if (depth && *depth >= 3) + *depth = *depth - 2 * border; +} + static void st_TexImage(GLcontext * ctx, @@ -483,15 +520,25 @@ st_TexImage(GLcontext * ctx, { struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); - GLint postConvWidth = width; - GLint postConvHeight = height; + GLint postConvWidth, postConvHeight; GLint texelBytes, sizeInBytes; GLuint dstRowStride; - + struct gl_pixelstore_attrib unpackNB; DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); + /* gallium does not support texture borders, strip it off */ + if (border) { + strip_texture_border(border, &width, &height, &depth, + unpack, &unpackNB); + unpack = &unpackNB; + border = 0; + } + + postConvWidth = width; + postConvHeight = height; + stImage->face = _mesa_tex_target_to_face(target); stImage->level = level; -- cgit v1.2.3 From e4026167d70f0aa0bc0cd2546ef9b41f7b167735 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 11 Feb 2008 09:42:02 -0700 Subject: gallium: implement software fallback for mipmap generation This is used when we can't render to the surface type of the texture (such as luminance/alpha). --- src/mesa/state_tracker/st_gen_mipmap.c | 68 ++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index a6ac9a55fb..5c00392af7 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -29,11 +29,14 @@ #include "main/imports.h" #include "main/mipmap.h" #include "main/teximage.h" +#include "main/texformat.h" #include "shader/prog_instruction.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" #include "pipe/cso_cache/cso_cache.h" #include "st_context.h" @@ -239,15 +242,18 @@ draw_quad(GLcontext *ctx) */ static boolean st_render_mipmap(struct st_context *st, + GLenum target, struct pipe_texture *pt, uint baseLevel, uint lastLevel) { struct pipe_context *pipe = st->pipe; struct pipe_framebuffer_state fb; - const uint face = 0, zslice = 0; + const uint face = _mesa_tex_target_to_face(target), zslice = 0; const uint first_level_save = pt->first_level; uint dstLevel; + assert(target != GL_TEXTURE_3D); /* not done yet */ + /* check if we can render in the texture's format */ if (!pipe->is_format_supported(pipe, pt->format, PIPE_SURFACE)) { return FALSE; @@ -307,6 +313,56 @@ st_render_mipmap(struct st_context *st, } +static void +fallback_generate_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + struct pipe_context *pipe = ctx->st->pipe; + struct pipe_winsys *ws = pipe->winsys; + struct pipe_texture *pt = st_get_texobj_texture(texObj); + const uint baseLevel = texObj->BaseLevel; + const uint lastLevel = pt->last_level; + const uint face = _mesa_tex_target_to_face(target), zslice = 0; + uint dstLevel; + GLenum datatype; + GLuint comps; + + assert(target != GL_TEXTURE_3D); /* not done yet */ + + _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat, + &datatype, &comps); + + for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { + const uint srcLevel = dstLevel - 1; + struct pipe_surface *srcSurf, *dstSurf; + const ubyte *srcData; + ubyte *dstData; + + srcSurf = pipe->get_tex_surface(pipe, pt, face, srcLevel, zslice); + dstSurf = pipe->get_tex_surface(pipe, pt, face, dstLevel, zslice); + + srcData = (ubyte *) ws->buffer_map(ws, srcSurf->buffer, + PIPE_BUFFER_USAGE_CPU_READ) + + srcSurf->offset; + dstData = (ubyte *) ws->buffer_map(ws, dstSurf->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE) + + dstSurf->offset; + + _mesa_generate_mipmap_level(target, datatype, comps, + 0 /*border*/, + pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], + srcData, + pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], + dstData); + + ws->buffer_unmap(ws, srcSurf->buffer); + ws->buffer_unmap(ws, dstSurf->buffer); + + pipe_surface_reference(&srcSurf, NULL); + pipe_surface_reference(&dstSurf, NULL); + } +} + void st_generate_mipmap(GLcontext *ctx, GLenum target, @@ -318,13 +374,11 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, const uint lastLevel = pt->last_level; uint dstLevel; - if (!st_render_mipmap(st, pt, baseLevel, lastLevel)) { - abort(); - /* XXX the following won't really work at this time */ - _mesa_generate_mipmap(ctx, target, texObj); - return; + if (!st_render_mipmap(st, target, pt, baseLevel, lastLevel)) { + fallback_generate_mipmap(ctx, target, texObj); } + /* Fill in the Mesa gl_texture_image fields */ for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; const struct gl_texture_image *srcImage @@ -336,7 +390,6 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, uint dstDepth = pt->depth[dstLevel]; uint border = srcImage->Border; - dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel); if (!dstImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); @@ -359,5 +412,4 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, stImage = (struct st_texture_image *) dstImage; stImage->pt = pt; } - } -- cgit v1.2.3 From 3d0fd8a6cf294d58df2d2ec4139192416a1a4078 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 11 Feb 2008 09:50:21 -0700 Subject: gallium: comments about mipmap gen --- src/mesa/state_tracker/st_gen_mipmap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 5c00392af7..f6af37cfac 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -273,6 +273,10 @@ st_render_mipmap(struct st_context *st, pipe->bind_fs_state(pipe, stfp->fs->data); pipe->bind_vs_state(pipe, stvp->cso->data); + /* + * XXX for small mipmap levels, it may be faster to use the software + * fallback path... + */ for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; @@ -348,6 +352,7 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, PIPE_BUFFER_USAGE_CPU_WRITE) + dstSurf->offset; + /* XXX need to take stride/pitch info into account... */ _mesa_generate_mipmap_level(target, datatype, comps, 0 /*border*/, pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], -- cgit v1.2.3 From b61b1a295b13a0ff2cf98c8d07e62147d71c08b9 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 11 Feb 2008 10:59:40 -0700 Subject: gallium: take pitch/stride into account in mipmap generation --- src/mesa/main/mipmap.c | 85 +++++++++++++++++++++------------- src/mesa/main/mipmap.h | 2 + src/mesa/state_tracker/st_gen_mipmap.c | 3 +- 3 files changed, 57 insertions(+), 33 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 721a227bb5..d3d1958951 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -447,23 +447,29 @@ make_1d_mipmap(GLenum datatype, GLuint comps, GLint border, /** - * XXX need to use the tex image's row stride! + * Strides are in bytes. If zero, it'll be computed as width * bpp. */ static void make_2d_mipmap(GLenum datatype, GLuint comps, GLint border, - GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, - GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) + GLint srcWidth, GLint srcHeight, + GLint srcRowStride, const GLubyte *srcPtr, + GLint dstWidth, GLint dstHeight, + GLint dstRowStride, GLubyte *dstPtr) { const GLint bpt = bytes_per_pixel(datatype, comps); const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint dstWidthNB = dstWidth - 2 * border; const GLint dstHeightNB = dstHeight - 2 * border; - const GLint srcRowStride = bpt * srcWidth; - const GLint dstRowStride = bpt * dstWidth; const GLubyte *srcA, *srcB; GLubyte *dst; GLint row; + if (!srcRowStride) + srcRowStride = bpt * srcWidth; + + if (!dstRowStride) + dstRowStride = bpt * dstWidth; + /* Compute src and dst pointers, skipping any border */ srcA = srcPtr + border * ((srcWidth + 1) * bpt); if (srcHeight > 1) @@ -535,8 +541,10 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border, static void make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint srcRowStride, const GLubyte *srcPtr, GLint dstWidth, GLint dstHeight, GLint dstDepth, + GLint dstRowStride, GLubyte *dstPtr) { const GLint bpt = bytes_per_pixel(datatype, comps); @@ -548,7 +556,6 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, GLvoid *tmpRowA, *tmpRowB; GLint img, row; GLint bytesPerSrcImage, bytesPerDstImage; - GLint bytesPerSrcRow, bytesPerDstRow; GLint srcImageOffset, srcRowOffset; (void) srcDepthNB; /* silence warnings */ @@ -566,8 +573,10 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, bytesPerSrcImage = srcWidth * srcHeight * bpt; bytesPerDstImage = dstWidth * dstHeight * bpt; - bytesPerSrcRow = srcWidth * bpt; - bytesPerDstRow = dstWidth * bpt; + if (!srcRowStride) + srcRowStride = srcWidth * bpt; + if (!dstRowStride) + dstRowStride = dstWidth * bpt; /* Offset between adjacent src images to be averaged together */ srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage; @@ -591,13 +600,13 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, for (img = 0; img < dstDepthNB; img++) { /* first source image pointer, skipping border */ const GLubyte *imgSrcA = srcPtr - + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border + + (bytesPerSrcImage + srcRowStride + border) * bpt * border + img * (bytesPerSrcImage + srcImageOffset); /* second source image pointer, skipping border */ const GLubyte *imgSrcB = imgSrcA + srcImageOffset; /* address of the dest image, skipping border */ GLubyte *imgDst = dstPtr - + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border + + (bytesPerDstImage + dstRowStride + border) * bpt * border + img * bytesPerDstImage; /* setup the four source row pointers and the dest row pointer */ @@ -618,11 +627,11 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, do_row(datatype, comps, srcWidthNB, tmpRowA, tmpRowB, dstWidthNB, dstImgRow); /* advance to next rows */ - srcImgARowA += bytesPerSrcRow + srcRowOffset; - srcImgARowB += bytesPerSrcRow + srcRowOffset; - srcImgBRowA += bytesPerSrcRow + srcRowOffset; - srcImgBRowB += bytesPerSrcRow + srcRowOffset; - dstImgRow += bytesPerDstRow; + srcImgARowA += srcRowStride + srcRowOffset; + srcImgARowB += srcRowStride + srcRowOffset; + srcImgBRowA += srcRowStride + srcRowOffset; + srcImgBRowB += srcRowStride + srcRowOffset; + dstImgRow += dstRowStride; } } @@ -632,12 +641,14 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, /* Luckily we can leverage the make_2d_mipmap() function here! */ if (border > 0) { /* do front border image */ - make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight, srcPtr, - dstWidth, dstHeight, dstPtr); + make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight, 0, srcPtr, + dstWidth, dstHeight, 0, dstPtr); /* do back border image */ make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight, + 0, srcPtr + bytesPerSrcImage * (srcDepth - 1), dstWidth, dstHeight, + 0, dstPtr + bytesPerDstImage * (dstDepth - 1)); /* do four remaining border edges that span the image slices */ if (srcDepth == dstDepth) { @@ -653,9 +664,9 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, /* do border along [img][row=dstHeight-1][col=0] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage - + (srcHeight - 1) * bytesPerSrcRow; + + (srcHeight - 1) * srcRowStride; dst = dstPtr + (img + 1) * bytesPerDstImage - + (dstHeight - 1) * bytesPerDstRow; + + (dstHeight - 1) * dstRowStride; MEMCPY(dst, src, bpt); /* do border along [img][row=0][col=dstWidth-1] */ @@ -687,9 +698,9 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, /* do border along [img][row=dstHeight-1][col=0] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage - + (srcHeight - 1) * bytesPerSrcRow; + + (srcHeight - 1) * srcRowStride; dst = dstPtr + (img + 1) * bytesPerDstImage - + (dstHeight - 1) * bytesPerDstRow; + + (dstHeight - 1) * dstRowStride; do_row(datatype, comps, 1, src, src + srcImageOffset, 1, dst); /* do border along [img][row=0][col=dstWidth-1] */ @@ -755,8 +766,11 @@ make_1d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, */ static void make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, - GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, + GLint srcWidth, GLint srcHeight, + GLint srcRowStride, + const GLubyte *srcPtr, GLint dstWidth, GLint dstHeight, GLint dstDepth, + GLint dstRowStride, GLubyte *dstPtr) { const GLint bpt = bytes_per_pixel(datatype, comps); @@ -764,13 +778,17 @@ make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, const GLint dstWidthNB = dstWidth - 2 * border; const GLint dstHeightNB = dstHeight - 2 * border; const GLint dstDepthNB = dstDepth - 2 * border; - const GLint srcRowStride = bpt * srcWidth; - const GLint dstRowStride = bpt * dstWidth; const GLubyte *srcA, *srcB; GLubyte *dst; GLint layer; GLint row; + if (!srcRowStride) + srcRowStride = bpt * srcWidth; + + if (!dstRowStride) + dstRowStride = bpt * dstWidth; + /* Compute src and dst pointers, skipping any border */ srcA = srcPtr + border * ((srcWidth + 1) * bpt); if (srcHeight > 1) @@ -849,8 +867,10 @@ _mesa_generate_mipmap_level(GLenum target, GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint srcRowStride, const GLubyte *srcData, GLint dstWidth, GLint dstHeight, GLint dstDepth, + GLint dstRowStride, GLubyte *dstData) { switch (target) { @@ -867,13 +887,13 @@ _mesa_generate_mipmap_level(GLenum target, case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: make_2d_mipmap(datatype, comps, border, - srcWidth, srcHeight, srcData, - dstWidth, dstHeight, dstData); + srcWidth, srcHeight, srcRowStride, srcData, + dstWidth, dstHeight, dstRowStride, dstData); break; case GL_TEXTURE_3D: make_3d_mipmap(datatype, comps, border, - srcWidth, srcHeight, srcDepth, srcData, - dstWidth, dstHeight, dstDepth, dstData); + srcWidth, srcHeight, srcDepth, srcRowStride, srcData, + dstWidth, dstHeight, dstDepth, dstRowStride, dstData); break; case GL_TEXTURE_1D_ARRAY_EXT: make_1d_stack_mipmap(datatype, comps, border, @@ -882,8 +902,8 @@ _mesa_generate_mipmap_level(GLenum target, break; case GL_TEXTURE_2D_ARRAY_EXT: make_2d_stack_mipmap(datatype, comps, border, - srcWidth, srcHeight, srcData, - dstWidth, dstHeight, dstDepth, dstData); + srcWidth, srcHeight, srcRowStride, srcData, + dstWidth, dstHeight, dstDepth, dstRowStride, dstData); break; case GL_TEXTURE_RECTANGLE_NV: /* no mipmaps, do nothing */ @@ -1110,9 +1130,10 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, dstData = (GLubyte *) dstImage->Data; } + /* Note, 0 indicates default row strides */ _mesa_generate_mipmap_level(target, datatype, comps, border, - srcWidth, srcHeight, srcDepth, srcData, - dstWidth, dstHeight, dstDepth, dstData); + srcWidth, srcHeight, srcDepth, 0, srcData, + dstWidth, dstHeight, dstDepth, 0, dstData); if (dstImage->IsCompressed) { GLubyte *temp; diff --git a/src/mesa/main/mipmap.h b/src/mesa/main/mipmap.h index b6491f5507..44ecdddb27 100644 --- a/src/mesa/main/mipmap.h +++ b/src/mesa/main/mipmap.h @@ -34,8 +34,10 @@ _mesa_generate_mipmap_level(GLenum target, GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint srcRowStride, const GLubyte *srcData, GLint dstWidth, GLint dstHeight, GLint dstDepth, + GLint dstRowStride, GLubyte *dstData); diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index f6af37cfac..c152c59905 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -352,12 +352,13 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, PIPE_BUFFER_USAGE_CPU_WRITE) + dstSurf->offset; - /* XXX need to take stride/pitch info into account... */ _mesa_generate_mipmap_level(target, datatype, comps, 0 /*border*/, pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], + srcSurf->pitch * srcSurf->cpp, /* stride in bytes */ srcData, pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], + dstSurf->pitch * dstSurf->cpp, /* stride in bytes */ dstData); ws->buffer_unmap(ws, srcSurf->buffer); -- cgit v1.2.3 From 4da1cdf78fa3b954840650fa46cf72da5daf149f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 14:53:25 -0700 Subject: gallium: clean-up, simplification of mipmapped textures Remove pipe_texture->first_level (always implicitly zero). This means there's never any unused mipmap levels at the top. In the state tracker, we no longer re-layout mipmapped textures if the MinLod/MaxLod texture parameters change. It's up to the driver to obey the pipe_sampler->min/max_lod clamps. --- src/mesa/pipe/i915simple/i915_state.c | 7 ++++ src/mesa/pipe/i915simple/i915_state_sampler.c | 2 +- src/mesa/pipe/i915simple/i915_texture.c | 30 +++++++-------- src/mesa/pipe/i965simple/brw_tex_layout.c | 8 ++-- src/mesa/pipe/i965simple/brw_wm_surface_state.c | 2 +- src/mesa/pipe/p_state.h | 14 ++----- src/mesa/pipe/softpipe/sp_state_sampler.c | 4 ++ src/mesa/pipe/softpipe/sp_tex_sample.c | 18 +++------ src/mesa/pipe/softpipe/sp_texture.c | 4 +- src/mesa/state_tracker/st_cb_texture.c | 51 +++++++++---------------- src/mesa/state_tracker/st_gen_mipmap.c | 43 ++++++++++++--------- src/mesa/state_tracker/st_texture.c | 35 ++++++++++++----- src/mesa/state_tracker/st_texture.h | 6 +-- 13 files changed, 115 insertions(+), 109 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 950ea52d60..abd5571b88 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -250,6 +250,13 @@ i915_create_sampler_state(struct pipe_context *pipe, if (sampler->normalized_coords) cso->state[1] |= SS3_NORMALIZED_COORDS; + if (0) /* XXX not tested yet */ + { + int minlod = (int) (16.0 * sampler->min_lod); + minlod = CLAMP(minlod, 0, 16 * 11); + cso->state[1] |= (minlod << SS3_MIN_LOD_SHIFT); + } + { ubyte r = float_to_ubyte(sampler->border_color[0]); ubyte g = float_to_ubyte(sampler->border_color[1]); diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c index 0dbbc5241d..9c1a5bbbd6 100644 --- a/src/mesa/pipe/i915simple/i915_state_sampler.c +++ b/src/mesa/pipe/i915simple/i915_state_sampler.c @@ -185,7 +185,7 @@ i915_update_texture(struct i915_context *i915, uint unit, const struct pipe_texture *pt = &tex->base; uint format, pitch; const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; - const uint num_levels = pt->last_level - pt->first_level; + const uint num_levels = pt->last_level; assert(tex); assert(width); diff --git a/src/mesa/pipe/i915simple/i915_texture.c b/src/mesa/pipe/i915simple/i915_texture.c index 6faeab134a..6d37ae3d74 100644 --- a/src/mesa/pipe/i915simple/i915_texture.c +++ b/src/mesa/pipe/i915simple/i915_texture.c @@ -118,11 +118,11 @@ i945_miptree_layout_2d( struct i915_texture *tex ) tex->pitch = pt->width[0]; /* May need to adjust pitch to accomodate the placement of - * the 2nd mipmap. This occurs when the alignment + * the 2nd mipmap level. This occurs when the alignment * constraints of mipmap placement push the right edge of the - * 2nd mipmap out past the width of its parent. + * 2nd mipmap level out past the width of its parent. */ - if (pt->first_level != pt->last_level) { + if (pt->last_level > 0) { unsigned mip1_width = align_int(minify(pt->width[0]), align_w) + minify(minify(pt->width[0])); @@ -136,7 +136,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp; tex->total_height = 0; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { unsigned img_height; i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); @@ -152,9 +152,9 @@ i945_miptree_layout_2d( struct i915_texture *tex ) */ tex->total_height = MAX2(tex->total_height, y + img_height); - /* Layout_below: step right after second mipmap. + /* Layout_below: step right after second mipmap level. */ - if (level == pt->first_level + 1) { + if (level == 1) { x += align_int(width, align_w); } else { @@ -204,7 +204,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; tex->total_height = dim * 4; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, 0, 0, /*OLD: tex->pitch, tex->total_height,*/ @@ -219,7 +219,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) unsigned y = initial_offsets[face][1] * dim; unsigned d = dim; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; x += step_offsets[face][0] * d; @@ -240,7 +240,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) /* XXX: hardware expects/requires 9 levels at minimum. */ - for (level = pt->first_level; level <= MAX2(8, pt->last_level); + for (level = 0; level <= MAX2(8, pt->last_level); level++) { i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height, width, height, depth); @@ -256,7 +256,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) /* Fixup depth image_offsets: */ depth = pt->depth[0]; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { unsigned i; for (i = 0; i < depth; i++) i915_miptree_set_image_offset(tex, level, i, @@ -282,7 +282,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; tex->total_height = 0; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 1, 0, tex->total_height, width, height, 1); @@ -337,7 +337,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) /* Set all the levels to effectively occupy the whole rectangular region. */ - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, 0, 0, lvlWidth, lvlHeight, 1); @@ -355,12 +355,12 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) y = tex->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0 || pt->first_level > 0)) { + else if (dim < 4 && (face > 0)) { y = tex->total_height - 4; x = face * 8; } - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; @@ -418,7 +418,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) pack_x_pitch = tex->pitch; pack_x_nr = 1; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; diff --git a/src/mesa/pipe/i965simple/brw_tex_layout.c b/src/mesa/pipe/i965simple/brw_tex_layout.c index 405fd1f794..90561f1307 100644 --- a/src/mesa/pipe/i965simple/brw_tex_layout.c +++ b/src/mesa/pipe/i965simple/brw_tex_layout.c @@ -146,7 +146,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (pt->first_level != pt->last_level) { + if (pt->last_level > 0) { unsigned mip1_width; if (pt->compressed) { @@ -168,7 +168,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp; tex->total_height = 0; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { unsigned img_height; intel_miptree_set_level_info(tex, level, 1, x, y, width, @@ -187,7 +187,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) /* Layout_below: step right after second mipmap. */ - if (level == pt->first_level + 1) { + if (level == 1) { x += align(width, align_w); } else { @@ -234,7 +234,7 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture pack_x_pitch = tex->pitch; pack_x_nr = 1; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; diff --git a/src/mesa/pipe/i965simple/brw_wm_surface_state.c b/src/mesa/pipe/i965simple/brw_wm_surface_state.c index cbb4f2efd3..d16d919bce 100644 --- a/src/mesa/pipe/i965simple/brw_wm_surface_state.c +++ b/src/mesa/pipe/i965simple/brw_wm_surface_state.c @@ -154,7 +154,7 @@ void brw_update_texture_surface( struct brw_context *brw, /* Updated in emit_reloc */ surf.ss1.base_addr = brw_buffer_offset( brw, tObj->buffer ); - surf.ss2.mip_count = tObj->base.last_level - tObj->base.first_level; + surf.ss2.mip_count = tObj->base.last_level; surf.ss2.width = tObj->base.width[0] - 1; surf.ss2.height = tObj->base.height[0] - 1; diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 83ca43f678..4d3a6b2f41 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -234,14 +234,9 @@ struct pipe_sampler_state unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ - float shadow_ambient; /**< shadow test fail color/intensity */ - float min_lod; - float max_lod; - float lod_bias; -#if 0 /* need these? */ - int BaseLevel; /**< min mipmap level, OpenGL 1.2 */ - int MaxLevel; /**< max mipmap level, OpenGL 1.2 */ -#endif + float shadow_ambient; /**< shadow test fail color/intensity */ + float lod_bias; /**< LOD/lambda bias */ + float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; float max_anisotropy; }; @@ -277,8 +272,7 @@ struct pipe_texture enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ enum pipe_format format; /**< PIPE_FORMAT_x */ - unsigned first_level; - unsigned last_level; + unsigned last_level; /**< Index of last mipmap level present/defined */ unsigned width[PIPE_MAX_TEXTURE_LEVELS]; unsigned height[PIPE_MAX_TEXTURE_LEVELS]; diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index 291bbc40ad..6a5a643c89 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -34,6 +34,8 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "pipe/draw/draw_context.h" + void * @@ -73,6 +75,8 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); + draw_flush(softpipe->draw); + assert(unit < PIPE_MAX_SAMPLERS); softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index 5e215c433a..325bdb86da 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -449,7 +449,6 @@ compute_lambda(struct tgsi_sampler *sampler, } lambda = LOG2(rho); - lambda += lodbias + sampler->state->lod_bias; lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); @@ -457,7 +456,6 @@ compute_lambda(struct tgsi_sampler *sampler, } - /** * Do several things here: * 1. Compute lambda from the texcoords, if needed @@ -477,7 +475,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ *imgFilter = sampler->state->mag_img_filter; - *level0 = *level1 = sampler->texture->first_level; + *level0 = *level1 = (int) sampler->state->min_lod; } else { float lambda; @@ -492,7 +490,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, if (lambda < 0.0) { /* XXX threshold depends on the filter */ /* magnifying */ *imgFilter = sampler->state->mag_img_filter; - *level0 = *level1 = sampler->texture->first_level; + *level0 = *level1 = 0; } else { /* minifying */ @@ -503,19 +501,13 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, /* Nearest mipmap level */ const int lvl = (int) (lambda + 0.5); *level0 = - *level1 = CLAMP(lvl, - (int) sampler->texture->first_level, - (int) sampler->texture->last_level); + *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); } else { /* Linear interpolation between mipmap levels */ const int lvl = (int) lambda; - *level0 = CLAMP(lvl, - (int) sampler->texture->first_level, - (int) sampler->texture->last_level); - *level1 = CLAMP(lvl + 1, - (int) sampler->texture->first_level, - (int) sampler->texture->last_level); + *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); + *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); *levelBlend = FRAC(lambda); /* blending weight between levels */ } } diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c index fd2cc3dbbb..6de7a9b543 100644 --- a/src/mesa/pipe/softpipe/sp_texture.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -61,7 +61,7 @@ softpipe_texture_layout(struct softpipe_texture * spt) spt->buffer_size = 0; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; @@ -139,6 +139,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe, struct softpipe_texture *spt = softpipe_texture(pt); struct pipe_surface *ps; + assert(level <= pt->last_level); + ps = pipe->winsys->surface_alloc(pipe->winsys); if (ps) { assert(ps->refcount); diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 7099ec33b9..f012b2f1a0 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -57,15 +57,10 @@ struct st_texture_object { struct gl_texture_object base; /* The "parent" object */ - /* The texture must include at least these levels once validated: + /* The texture must include at levels [0..lastLevel] once validated: */ - GLuint firstLevel; GLuint lastLevel; - /* Offset for firstLevel image: - */ - GLuint textureOffset; - /* On validation any active images held in main memory or in other * textures will be copied to this texture and the old storage freed. */ @@ -585,12 +580,12 @@ st_TexImage(GLcontext * ctx, _mesa_align_free(texImage->Data); } - /* If this is the only texture image in the texture, could call + /* If this is the only mipmap level in the texture, could call * bmBufferData with NULL data to free the old block and avoid * waiting on any outstanding fences. */ if (stObj->pt && - stObj->pt->first_level == level && + /*stObj->pt->first_level == level &&*/ stObj->pt->last_level == level && stObj->pt->target != PIPE_TEXTURE_CUBE && !st_texture_match_image(stObj->pt, &stImage->base, @@ -1363,13 +1358,8 @@ calculate_first_last_level(struct st_texture_object *stObj) firstLevel = lastLevel = tObj->BaseLevel; } else { - firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + firstLevel = 0; + lastLevel = MIN2(tObj->MaxLevel - tObj->BaseLevel, baseImage->MaxLog2); } break; case GL_TEXTURE_RECTANGLE_NV: @@ -1380,8 +1370,6 @@ calculate_first_last_level(struct st_texture_object *stObj) return; } - /* save these values */ - stObj->firstLevel = firstLevel; stObj->lastLevel = lastLevel; } @@ -1389,15 +1377,16 @@ calculate_first_last_level(struct st_texture_object *stObj) static void copy_image_data_to_texture(struct st_context *st, struct st_texture_object *stObj, + GLuint dstLevel, struct st_texture_image *stImage) { if (stImage->pt) { /* Copy potentially with the blitter: */ st_texture_image_copy(st->pipe, - stObj->pt, /* dest texture */ - stImage->face, stImage->level, - stImage->pt /* src texture */ + stObj->pt, dstLevel, /* dest texture, level */ + stImage->pt, /* src texture */ + stImage->face ); st->pipe->texture_release(st->pipe, &stImage->pt); @@ -1438,7 +1427,7 @@ st_finalize_texture(GLcontext *ctx, const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; int comp_byte = 0; int cpp; - GLuint face, i; + GLuint face; struct st_texture_image *firstImage; *needFlush = GL_FALSE; @@ -1450,7 +1439,7 @@ st_finalize_texture(GLcontext *ctx, /* What levels must the texture include at a minimum? */ calculate_first_last_level(stObj); - firstImage = st_texture_image(stObj->base.Image[0][stObj->firstLevel]); + firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); /* Fallback case: */ @@ -1469,7 +1458,6 @@ st_finalize_texture(GLcontext *ctx, */ if (firstImage->pt && firstImage->pt != stObj->pt && - firstImage->pt->first_level <= stObj->firstLevel && firstImage->pt->last_level >= stObj->lastLevel) { if (stObj->pt) @@ -1488,18 +1476,11 @@ st_finalize_texture(GLcontext *ctx, /* Check texture can hold all active levels. Check texture matches * target, imageFormat, etc. - * - * XXX: For some layouts (eg i945?), the test might have to be - * first_level == firstLevel, as the texture isn't valid except at the - * original start level. Hope to get around this by - * programming minLod, maxLod, baseLevel into the hardware and - * leaving the texture alone. */ if (stObj->pt && (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || stObj->pt->format != st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) || - stObj->pt->first_level != stObj->firstLevel || stObj->pt->last_level != stObj->lastLevel || stObj->pt->width[0] != firstImage->base.Width || stObj->pt->height[0] != firstImage->base.Height || @@ -1516,7 +1497,7 @@ st_finalize_texture(GLcontext *ctx, stObj->pt = st_texture_create(ctx->st, gl_target_to_pipe(stObj->base.Target), st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), - stObj->firstLevel, + 0, /* first level */ stObj->lastLevel, firstImage->base.Width, firstImage->base.Height, @@ -1527,14 +1508,16 @@ st_finalize_texture(GLcontext *ctx, /* Pull in any images not in the object's texture: */ for (face = 0; face < nr_faces; face++) { - for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) { + GLuint level; + for (level = 0; level <= stObj->lastLevel; level++) { struct st_texture_image *stImage = - st_texture_image(stObj->base.Image[face][i]); + //st_texture_image(stObj->base.Image[face][level]); + st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); /* Need to import images in main memory or held in other textures. */ if (stObj->pt != stImage->pt) { - copy_image_data_to_texture(ctx->st, stObj, stImage); + copy_image_data_to_texture(ctx->st, stObj, level, stImage); *needFlush = GL_TRUE; } } diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index c152c59905..fd7d8cefea 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -51,7 +51,6 @@ static void *blend_cso = NULL; static void *depthstencil_cso = NULL; static void *rasterizer_cso = NULL; -static void *sampler_cso = NULL; static struct st_fragment_program *stfp = NULL; static struct st_vertex_program *stvp = NULL; @@ -118,7 +117,6 @@ st_init_generate_mipmap(struct st_context *st) struct pipe_context *pipe = st->pipe; struct pipe_blend_state blend; struct pipe_rasterizer_state rasterizer; - struct pipe_sampler_state sampler; struct pipe_depth_stencil_alpha_state depthstencil; assert(!blend_cso); @@ -133,16 +131,6 @@ st_init_generate_mipmap(struct st_context *st) memset(&rasterizer, 0, sizeof(rasterizer)); rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer); - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.normalized_coords = 1; - sampler_cso = pipe->create_sampler_state(pipe, &sampler); - stfp = make_tex_fragment_program(st->ctx); stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); } @@ -156,14 +144,12 @@ st_destroy_generate_mipmpap(struct st_context *st) pipe->delete_blend_state(pipe, blend_cso); pipe->delete_depth_stencil_alpha_state(pipe, depthstencil_cso); pipe->delete_rasterizer_state(pipe, rasterizer_cso); - pipe->delete_sampler_state(pipe, sampler_cso); /* XXX free stfp, stvp */ blend_cso = NULL; depthstencil_cso = NULL; rasterizer_cso = NULL; - sampler_cso = NULL; } @@ -248,8 +234,10 @@ st_render_mipmap(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_framebuffer_state fb; + struct pipe_sampler_state sampler; + void *sampler_cso; const uint face = _mesa_tex_target_to_face(target), zslice = 0; - const uint first_level_save = pt->first_level; + /*const uint first_level_save = pt->first_level;*/ uint dstLevel; assert(target != GL_TEXTURE_3D); /* not done yet */ @@ -263,11 +251,21 @@ st_render_mipmap(struct st_context *st, memset(&fb, 0, sizeof(fb)); fb.num_cbufs = 1; + /* sampler state */ + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.normalized_coords = 1; + + /* bind CSOs */ pipe->bind_blend_state(pipe, blend_cso); pipe->bind_depth_stencil_alpha_state(pipe, depthstencil_cso); pipe->bind_rasterizer_state(pipe, rasterizer_cso); - pipe->bind_sampler_state(pipe, 0, sampler_cso); /* bind shaders */ pipe->bind_fs_state(pipe, stfp->fs->data); @@ -286,20 +284,29 @@ st_render_mipmap(struct st_context *st, fb.cbufs[0] = pipe->get_tex_surface(pipe, pt, face, dstLevel, zslice); pipe->set_framebuffer_state(pipe, &fb); + /* + * Setup sampler state + */ + sampler.min_lod = sampler.max_lod = srcLevel; + sampler_cso = pipe->create_sampler_state(pipe, &sampler); + pipe->bind_sampler_state(pipe, 0, sampler_cso); + simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); /* * Setup src texture, override pt->first_level so we sample from * the right mipmap level. */ - pt->first_level = srcLevel; + /*pt->first_level = srcLevel;*/ pipe->set_sampler_texture(pipe, 0, pt); draw_quad(st->ctx); + + pipe->delete_sampler_state(pipe, sampler_cso); } /* restore first_level */ - pt->first_level = first_level_save; + /*pt->first_level = first_level_save;*/ /* restore pipe state */ if (st->state.rasterizer) diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 844a9f80d8..ff33da6f9e 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -62,6 +62,10 @@ target_to_target(GLenum target) /** * Allocate a new pipe_texture object + * width0, height0, depth0 are the dimensions of the level 0 image + * (the highest resolution). last_level indicates how many mipmap levels + * to allocate storage for. For non-mipmapped textures, this will be zero. + * XXX first_level obsolete */ struct pipe_texture * st_texture_create(struct st_context *st, @@ -84,9 +88,9 @@ st_texture_create(struct st_context *st, assert(format); + memset(&pt, 0, sizeof(pt)); pt.target = target; pt.format = format; - pt.first_level = first_level; pt.last_level = last_level; pt.width[0] = width0; pt.height[0] = height0; @@ -266,23 +270,36 @@ st_texture_image_data(struct pipe_context *pipe, */ void st_texture_image_copy(struct pipe_context *pipe, - struct pipe_texture *dst, - GLuint face, GLuint level, - struct pipe_texture *src) + struct pipe_texture *dst, GLuint dstLevel, + struct pipe_texture *src, + GLuint face) { - GLuint width = src->width[level]; - GLuint height = src->height[level]; - GLuint depth = src->depth[level]; + GLuint width = dst->width[dstLevel]; + GLuint height = dst->height[dstLevel]; + GLuint depth = dst->depth[dstLevel]; struct pipe_surface *src_surface; struct pipe_surface *dst_surface; GLuint i; + /* XXX this is a hack */ if (dst->compressed) height /= 4; for (i = 0; i < depth; i++) { - dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i); - src_surface = pipe->get_tex_surface(pipe, src, face, level, i); + GLuint srcLevel; + + /* find src texture level of needed size */ + for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) { + if (src->width[srcLevel] == width && + src->height[srcLevel] == height) { + break; + } + } + assert(src->width[srcLevel] == width); + assert(src->height[srcLevel] == height); + + dst_surface = pipe->get_tex_surface(pipe, dst, face, dstLevel, i); + src_surface = pipe->get_tex_surface(pipe, src, face, srcLevel, i); pipe->surface_copy(pipe, dst_surface, diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 0b87a494c3..6c5f0930fa 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -98,9 +98,9 @@ st_texture_image_data(struct pipe_context *pipe, */ extern void st_texture_image_copy(struct pipe_context *pipe, - struct pipe_texture *dst, - GLuint face, GLuint level, - struct pipe_texture *src); + struct pipe_texture *dst, GLuint dstLevel, + struct pipe_texture *src, + GLuint face); #endif -- cgit v1.2.3 From 1d62a057bcb3ee4ef6ebedd93f62ed2e0d8061ba Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 14:55:51 -0700 Subject: gallium: remove unused first_level param from st_texture_create() --- src/mesa/state_tracker/st_cb_drawpixels.c | 6 +++--- src/mesa/state_tracker/st_cb_texture.c | 2 -- src/mesa/state_tracker/st_texture.c | 6 ++---- src/mesa/state_tracker/st_texture.h | 1 - 4 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 07886e7982..475e23653e 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -471,7 +471,7 @@ make_texture(struct st_context *st, assert(pipeFormat); cpp = st_sizeof_format(pipeFormat); - pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, 0, width, height, + pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1, 0); if (!pt) return NULL; @@ -1017,7 +1017,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, /** * Create a texture. */ - pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, 0, width, height, + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height, 1, 0); if (!pt) return NULL; @@ -1241,7 +1241,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, psRead = rbRead->surface; format = psRead->format; - pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, 0, width, height, + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height, 1, 0); if (!pt) return; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index f012b2f1a0..fab9eafc7f 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -363,7 +363,6 @@ guess_and_alloc_texture(struct st_context *st, stObj->pt = st_texture_create(st, gl_target_to_pipe(stObj->base.Target), st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat), - firstLevel, lastLevel, width, height, @@ -1497,7 +1496,6 @@ st_finalize_texture(GLcontext *ctx, stObj->pt = st_texture_create(ctx->st, gl_target_to_pipe(stObj->base.Target), st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), - 0, /* first level */ stObj->lastLevel, firstImage->base.Width, firstImage->base.Height, diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index ff33da6f9e..2622d00953 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -65,13 +65,11 @@ target_to_target(GLenum target) * width0, height0, depth0 are the dimensions of the level 0 image * (the highest resolution). last_level indicates how many mipmap levels * to allocate storage for. For non-mipmapped textures, this will be zero. - * XXX first_level obsolete */ struct pipe_texture * st_texture_create(struct st_context *st, enum pipe_texture_target target, enum pipe_format format, - GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, @@ -82,9 +80,9 @@ st_texture_create(struct st_context *st, assert(target <= PIPE_TEXTURE_CUBE); - DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, + DBG("%s target %s format %s last_level %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(format), first_level, last_level); + _mesa_lookup_enum_by_nr(format), last_level); assert(format); diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 6c5f0930fa..72324cd9ab 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -39,7 +39,6 @@ extern struct pipe_texture * st_texture_create(struct st_context *st, enum pipe_texture_target target, enum pipe_format format, - GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, -- cgit v1.2.3 From 6d53b8f42349c507e7184aa567a4b2a4fc7b037f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 16:06:51 -0700 Subject: gallium: move gen-mipmap global/static vars into st_context This fixes potential problems with multi-context programs. --- src/mesa/state_tracker/st_context.h | 9 ++++++++ src/mesa/state_tracker/st_gen_mipmap.c | 41 +++++++++++----------------------- 2 files changed, 22 insertions(+), 28 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index a756055898..59d1590f05 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -166,6 +166,15 @@ struct st_context struct st_fragment_program *combined_prog; } bitmap; + /** For gen/render mipmap feature */ + struct { + void *blend_cso; + void *depthstencil_cso; + void *rasterizer_cso; + struct st_fragment_program *stfp; + struct st_vertex_program *stvp; + } gen_mipmap; + struct cso_cache *cache; }; diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index fd7d8cefea..b4a21fd7e2 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -48,15 +48,6 @@ -static void *blend_cso = NULL; -static void *depthstencil_cso = NULL; -static void *rasterizer_cso = NULL; - -static struct st_fragment_program *stfp = NULL; -static struct st_vertex_program *stvp = NULL; - - - static struct st_fragment_program * make_tex_fragment_program(GLcontext *ctx) { @@ -119,20 +110,18 @@ st_init_generate_mipmap(struct st_context *st) struct pipe_rasterizer_state rasterizer; struct pipe_depth_stencil_alpha_state depthstencil; - assert(!blend_cso); - memset(&blend, 0, sizeof(blend)); blend.colormask = PIPE_MASK_RGBA; - blend_cso = pipe->create_blend_state(pipe, &blend); + st->gen_mipmap.blend_cso = pipe->create_blend_state(pipe, &blend); memset(&depthstencil, 0, sizeof(depthstencil)); - depthstencil_cso = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + st->gen_mipmap.depthstencil_cso = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); memset(&rasterizer, 0, sizeof(rasterizer)); - rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer); + st->gen_mipmap.rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer); - stfp = make_tex_fragment_program(st->ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + st->gen_mipmap.stfp = make_tex_fragment_program(st->ctx); + st->gen_mipmap.stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); } @@ -141,15 +130,11 @@ st_destroy_generate_mipmpap(struct st_context *st) { struct pipe_context *pipe = st->pipe; - pipe->delete_blend_state(pipe, blend_cso); - pipe->delete_depth_stencil_alpha_state(pipe, depthstencil_cso); - pipe->delete_rasterizer_state(pipe, rasterizer_cso); + pipe->delete_blend_state(pipe, st->gen_mipmap.blend_cso); + pipe->delete_depth_stencil_alpha_state(pipe, st->gen_mipmap.depthstencil_cso); + pipe->delete_rasterizer_state(pipe, st->gen_mipmap.rasterizer_cso); /* XXX free stfp, stvp */ - - blend_cso = NULL; - depthstencil_cso = NULL; - rasterizer_cso = NULL; } @@ -263,13 +248,13 @@ st_render_mipmap(struct st_context *st, /* bind CSOs */ - pipe->bind_blend_state(pipe, blend_cso); - pipe->bind_depth_stencil_alpha_state(pipe, depthstencil_cso); - pipe->bind_rasterizer_state(pipe, rasterizer_cso); + pipe->bind_blend_state(pipe, st->gen_mipmap.blend_cso); + pipe->bind_depth_stencil_alpha_state(pipe, st->gen_mipmap.depthstencil_cso); + pipe->bind_rasterizer_state(pipe, st->gen_mipmap.rasterizer_cso); /* bind shaders */ - pipe->bind_fs_state(pipe, stfp->fs->data); - pipe->bind_vs_state(pipe, stvp->cso->data); + pipe->bind_fs_state(pipe, st->gen_mipmap.stfp->fs->data); + pipe->bind_vs_state(pipe, st->gen_mipmap.stvp->cso->data); /* * XXX for small mipmap levels, it may be faster to use the software -- cgit v1.2.3 From 9677336845511be4852520d2e50f91f1df362f58 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 16:10:11 -0700 Subject: gallium: rename st_fragment_program's fs field to cso to match st_vertex_program --- src/mesa/state_tracker/st_atom_shader.c | 8 ++++---- src/mesa/state_tracker/st_cb_clear.c | 2 +- src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- src/mesa/state_tracker/st_cb_program.c | 4 ++-- src/mesa/state_tracker/st_gen_mipmap.c | 2 +- src/mesa/state_tracker/st_program.c | 2 +- src/mesa/state_tracker/st_program.h | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 9196918509..2c6ec8421b 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -158,7 +158,7 @@ find_translated_vp(struct st_context *st, /* * Translate fragment program if needed. */ - if (!stfp->fs) { + if (!stfp->cso) { GLuint inAttr, numIn = 0; for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) { @@ -179,7 +179,7 @@ find_translated_vp(struct st_context *st, stfp->input_to_slot, stfp->tokens, ST_MAX_SHADER_TOKENS); - assert(stfp->fs); + assert(stfp->cso); } @@ -227,7 +227,7 @@ find_translated_vp(struct st_context *st, if (fpInAttrib >= 0) { GLuint fpInSlot = stfp->input_to_slot[fpInAttrib]; if (fpInSlot != ~0) { - GLuint vpOutSlot = stfp->fs->state.input_map[fpInSlot]; + GLuint vpOutSlot = stfp->cso->state.input_map[fpInSlot]; xvp->output_to_slot[outAttr] = vpOutSlot; numVpOuts++; } @@ -300,7 +300,7 @@ update_linkage( struct st_context *st ) st->pipe->bind_vs_state(st->pipe, st->state.vs->cso->data); st->fp = stfp; - st->state.fs = stfp->fs; + st->state.fs = stfp->cso; st->pipe->bind_fs_state(st->pipe, st->state.fs->data); st->vertex_result_to_slot = xvp->output_to_slot; diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index ab98b54bab..410062e1e8 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -341,7 +341,7 @@ clear_with_quad(GLcontext *ctx, if (!stfp) { stfp = make_frag_shader(st); } - pipe->bind_fs_state(pipe, stfp->fs->data); + pipe->bind_fs_state(pipe, stfp->cso->data); } /* vertex shader state: color/position pass-through */ diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 475e23653e..3245a7488b 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -665,7 +665,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* fragment shader state: TEX lookup program */ - pipe->bind_fs_state(pipe, stfp->fs->data); + pipe->bind_fs_state(pipe, stfp->cso->data); /* vertex shader state: position + texcoord pass-through */ pipe->bind_vs_state(pipe, stvp->cso->data); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index f1f33fb0dd..af3ee65504 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -168,10 +168,10 @@ static void st_program_string_notify( GLcontext *ctx, stfp->serialNo++; - if (stfp->fs) { + if (stfp->cso) { /* free the TGSI code */ // cso_delete(stfp->vs); - stfp->fs = NULL; + stfp->cso = NULL; } stfp->param_state = stfp->Base.Base.Parameters->StateFlags; diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index b4a21fd7e2..459941cca8 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -253,7 +253,7 @@ st_render_mipmap(struct st_context *st, pipe->bind_rasterizer_state(pipe, st->gen_mipmap.rasterizer_cso); /* bind shaders */ - pipe->bind_fs_state(pipe, st->gen_mipmap.stfp->fs->data); + pipe->bind_fs_state(pipe, st->gen_mipmap.stfp->cso->data); pipe->bind_vs_state(pipe, st->gen_mipmap.stvp->cso->data); /* diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 84a9094001..c8297baded 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -420,7 +420,7 @@ st_translate_fragment_program(struct st_context *st, fs.tokens = tokensOut; cso = st_cached_fs_state(st, &fs); - stfp->fs = cso; + stfp->cso = cso; if (0) _mesa_print_program(&stfp->Base.Base); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index de02c3185f..ea1dde4a7a 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -62,7 +62,7 @@ struct st_fragment_program struct tgsi_token tokens[ST_MAX_SHADER_TOKENS]; /** Pointer to the corresponding cached shader */ - const struct cso_fragment_shader *fs; + const struct cso_fragment_shader *cso; GLuint param_state; -- cgit v1.2.3 From a34b43b3f4817268ef4b3f186203b5fbafc7214e Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 16:37:49 -0700 Subject: gallium: added null ptr check --- src/mesa/state_tracker/st_cb_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index fab9eafc7f..c6fe928d47 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1514,7 +1514,7 @@ st_finalize_texture(GLcontext *ctx, /* Need to import images in main memory or held in other textures. */ - if (stObj->pt != stImage->pt) { + if (stImage && stObj->pt != stImage->pt) { copy_image_data_to_texture(ctx->st, stObj, level, stImage); *needFlush = GL_TRUE; } -- cgit v1.2.3 From 508b73289de5c4e16b31ae7267140efbb0f319a5 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 16:38:56 -0700 Subject: gallium: remove dead code --- src/mesa/state_tracker/st_cb_texture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c6fe928d47..0ea367549b 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1509,7 +1509,6 @@ st_finalize_texture(GLcontext *ctx, GLuint level; for (level = 0; level <= stObj->lastLevel; level++) { struct st_texture_image *stImage = - //st_texture_image(stObj->base.Image[face][level]); st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); /* Need to import images in main memory or held in other textures. -- cgit v1.2.3 From 48e223a0db85e83e180a49f3c3c7ea4101a86f40 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 17:07:27 -0700 Subject: gallium: clamp min_lod so it's never negative --- src/mesa/state_tracker/st_atom_sampler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 6241e70b55..92263cb688 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -147,7 +147,7 @@ update_samplers(struct st_context *st) sampler.lod_bias = st->ctx->Texture.Unit[su].LodBias; #if 1 - sampler.min_lod = texobj->MinLod; + sampler.min_lod = (texobj->MinLod) < 0.0 ? 0.0 : texobj->MinLod; sampler.max_lod = texobj->MaxLod; #else /* min/max lod should really be as follows (untested). -- cgit v1.2.3 From 9af687c53037afe57e765f705906e12a86865c03 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 17:44:57 -0700 Subject: gallium: fix/finish glReadPixels(GL_DEPTH_COMPONENT). This fixes demos/reflect ('d' key) and tests/zreaddraw.c --- src/mesa/state_tracker/st_cb_readpixels.c | 99 ++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 21 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index a1bbb3a831..868c5f3c5f 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -180,20 +180,13 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (!strb) return; + if (format == GL_RGBA && type == GL_FLOAT) { /* write tile(row) directly into user's buffer */ df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width, height, format, type, 0, 0); dfStride = width * 4; } -#if 0 - else if (format == GL_DEPTH_COMPONENT && type == GL_FLOAT) { - /* write tile(row) directly into user's buffer */ - df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width, - height, format, type, 0, 0); - dfStride = width; - } -#endif else { /* write tile(row) into temp row buffer */ df = (GLfloat *) temp; @@ -209,22 +202,86 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, yStep = 1; } - /* Do a row at a time to flip image data vertically */ - for (i = 0; i < height; i++) { - pipe_get_tile_rgba(pipe, strb->surface, x, y, width, 1, df); - y += yStep; - df += dfStride; - if (!dfStride) { - /* convert GLfloat to user's format/type */ - GLvoid *dst = _mesa_image_address2d(&clippedPacking, dest, width, - height, format, type, i, 0); + /* + * Copy pixels from pipe_surface to user memory + */ + { + /* dest of first pixel in client memory */ + GLubyte *dst = _mesa_image_address2d(&clippedPacking, dest, width, + height, format, type, 0, 0); + /* dest row stride */ + const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width, + format, type); + + if (strb->surface->format == PIPE_FORMAT_S8Z24_UNORM) { if (format == GL_DEPTH_COMPONENT) { - _mesa_pack_depth_span(ctx, width, dst, type, - (GLfloat *) temp, &clippedPacking); + for (i = 0; i < height; i++) { + GLuint ztemp[MAX_WIDTH], j; + GLfloat zfloat[MAX_WIDTH]; + const double scale = 1.0 / ((1 << 24) - 1); + pipe_get_tile_raw(pipe, strb->surface, x, y, + width, 1, ztemp, 0); + y += yStep; + for (j = 0; j < width; j++) { + zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); + } + _mesa_pack_depth_span(ctx, width, dst, type, + zfloat, &clippedPacking); + dst += dstStride; + } } else { - _mesa_pack_rgba_span_float(ctx, width, temp, format, type, dst, - &clippedPacking, transferOps); + /* untested, but simple: */ + assert(format == GL_DEPTH_STENCIL_EXT); + for (i = 0; i < height; i++) { + pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, dst, 0); + y += yStep; + dst += dstStride; + } + } + } + else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) { + for (i = 0; i < height; i++) { + GLshort ztemp[MAX_WIDTH], j; + GLfloat zfloat[MAX_WIDTH]; + const double scale = 1.0 / 0xffff; + pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0); + y += yStep; + for (j = 0; j < width; j++) { + zfloat[j] = (float) (scale * ztemp[j]); + } + _mesa_pack_depth_span(ctx, width, dst, type, + zfloat, &clippedPacking); + dst += dstStride; + } + } + else if (strb->surface->format == PIPE_FORMAT_Z32_UNORM) { + for (i = 0; i < height; i++) { + GLuint ztemp[MAX_WIDTH], j; + GLfloat zfloat[MAX_WIDTH]; + const double scale = 1.0 / 0xffffffff; + pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0); + y += yStep; + for (j = 0; j < width; j++) { + zfloat[j] = (float) (scale * ztemp[j]); + } + _mesa_pack_depth_span(ctx, width, dst, type, + zfloat, &clippedPacking); + dst += dstStride; + } + } + else { + /* RGBA format */ + /* Do a row at a time to flip image data vertically */ + for (i = 0; i < height; i++) { + pipe_get_tile_rgba(pipe, strb->surface, x, y, width, 1, df); + y += yStep; + df += dfStride; + if (!dfStride) { + _mesa_pack_rgba_span_float(ctx, width, temp, format, type, dst, + &clippedPacking, transferOps); + dst += dstStride; + } } } } -- cgit v1.2.3