From: Brian Paul Date: Tue, 6 May 2008 19:47:41 +0000 (-0600) Subject: gallium: create drawing surfaces as GPU_READ/WRITE only X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=296378b6c8b205048244746e260739448c4ee590;p=mesa.git gallium: create drawing surfaces as GPU_READ/WRITE only Create different temporary surfaces for CPU_READ/WRITE when needed (such as for glReadPixels, glAccum, some glCopy/DrawPixels, glCopyTexSubImage, etc). --- diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index e4ef3e16b7d..8098d75e18f 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -105,7 +105,7 @@ void st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { struct st_renderbuffer *acc_strb = st_renderbuffer(rb); - struct pipe_surface *acc_ps = acc_strb->surface; + struct pipe_surface *acc_ps; struct pipe_screen *screen = ctx->st->pipe->screen; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; @@ -113,6 +113,8 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) const GLint height = ctx->DrawBuffer->_Ymax - ypos; GLvoid *map; + acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); map = screen->surface_map(screen, acc_ps, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -143,6 +145,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) } screen->surface_unmap(screen, acc_ps); + pipe_surface_reference(&acc_ps, NULL); } @@ -185,70 +188,100 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, static void accum_accum(struct pipe_context *pipe, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, - struct pipe_surface *acc_ps, - struct pipe_surface *color_ps) + struct st_renderbuffer *acc_strb, + struct st_renderbuffer *color_strb) { + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *acc_surf, *color_surf; GLfloat *colorBuf, *accBuf; GLint i; + acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + (PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ)); + + color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf); - acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, colorBuf); + acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); for (i = 0; i < 4 * width * height; i++) { accBuf[i] = accBuf[i] + colorBuf[i] * value; } - acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); free(colorBuf); free(accBuf); + pipe_surface_reference(&acc_surf, NULL); + pipe_surface_reference(&color_surf, NULL); } static void accum_load(struct pipe_context *pipe, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, - struct pipe_surface *acc_ps, - struct pipe_surface *color_ps) + struct st_renderbuffer *acc_strb, + struct st_renderbuffer *color_strb) { + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *acc_surf, *color_surf; GLfloat *buf; GLint i; + acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + + color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, buf); + pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, buf); for (i = 0; i < 4 * width * height; i++) { buf[i] = buf[i] * value; } - acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf); + acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf); free(buf); + pipe_surface_reference(&acc_surf, NULL); + pipe_surface_reference(&color_surf, NULL); } static void accum_return(GLcontext *ctx, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, - struct pipe_surface *acc_ps, - struct pipe_surface *color_ps) + struct st_renderbuffer *acc_strb, + struct st_renderbuffer *color_strb) { struct pipe_context *pipe = ctx->st->pipe; + struct pipe_screen *screen = pipe->screen; const GLubyte *colormask = ctx->Color.ColorMask; + struct pipe_surface *acc_surf, *color_surf; GLfloat *abuf, *cbuf = NULL; GLint i, ch; abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf); + acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + + color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, + (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE)); + + acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf); if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, cbuf); + pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, cbuf); } for (i = 0; i < width * height; i++) { @@ -263,11 +296,13 @@ accum_return(GLcontext *ctx, GLfloat value, } } - pipe_put_tile_rgba(pipe, color_ps, xpos, ypos, width, height, abuf); + pipe_put_tile_rgba(pipe, color_surf, xpos, ypos, width, height, abuf); free(abuf); if (cbuf) free(cbuf); + pipe_surface_reference(&acc_surf, NULL); + pipe_surface_reference(&color_surf, NULL); } @@ -280,8 +315,6 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); struct st_renderbuffer *color_strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); - struct pipe_surface *acc_ps = acc_strb->surface; - struct pipe_surface *color_ps = color_strb->surface; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; @@ -304,14 +337,14 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) break; case GL_ACCUM: if (value != 0.0F) { - accum_accum(pipe, value, xpos, ypos, width, height, acc_ps, color_ps); + accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); } break; case GL_LOAD: - accum_load(pipe, value, xpos, ypos, width, height, acc_ps, color_ps); + accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); break; case GL_RETURN: - accum_return(ctx, value, xpos, ypos, width, height, acc_ps, color_ps); + accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb); break; default: assert(0); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 6ec3c343cda..c967c989de5 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -734,13 +734,19 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct st_context *st = ctx->st; struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_surface *ps = st->state.framebuffer.zsbuf; + struct st_renderbuffer *strb; + struct pipe_surface *ps; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; ubyte *stmap; pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + strb = st_renderbuffer(ctx->DrawBuffer-> + Attachment[BUFFER_STENCIL].Renderbuffer); + ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + /* map the stencil buffer */ stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -801,6 +807,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* unmap the stencil buffer */ screen->surface_unmap(screen, ps); + pipe_surface_reference(&ps, NULL); } @@ -874,7 +881,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); struct pipe_screen *screen = ctx->st->pipe->screen; - struct pipe_surface *psDraw = rbDraw->surface; + struct pipe_surface *psDraw; ubyte *drawMap; ubyte *buffer; int i; @@ -889,6 +896,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); + psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + /* map the stencil buffer */ drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -931,6 +941,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* unmap the stencil buffer */ screen->surface_unmap(screen, psDraw); + pipe_surface_reference(&psDraw, NULL); } @@ -945,7 +956,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct st_renderbuffer *rbRead; struct st_vertex_program *stvp; struct st_fragment_program *stfp; - struct pipe_surface *psRead; struct pipe_surface *psTex; struct pipe_texture *pt; GLfloat *color; @@ -976,8 +986,12 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE); } +#if 0 psRead = rbRead->surface; srcFormat = psRead->format; +#else + srcFormat = rbRead->texture->format; +#endif if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) { texFormat = srcFormat; @@ -1005,18 +1019,26 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (srcFormat == texFormat) { + /* copy source framebuffer surface into mipmap/texture */ + struct pipe_surface *psRead = screen->get_tex_surface(screen, + rbRead->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ); psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE ); - - /* copy source framebuffer surface into mipmap/texture */ pipe->surface_copy(pipe, FALSE, psTex, /* dest */ 0, 0, /* destx/y */ psRead, srcx, srcy, width, height); + pipe_surface_reference(&psRead, NULL); } else { + /* CPU-based fallback/conversion */ + struct pipe_surface *psRead = screen->get_tex_surface(screen, + rbRead->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE ); @@ -1036,6 +1058,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf); free(buf); } + pipe_surface_reference(&psRead, NULL); } pipe_surface_reference(&psTex, NULL); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index e0578f0b4d7..747d4905e6b 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -95,7 +95,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, { struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); - struct pipe_texture template, *texture; + struct pipe_texture template; unsigned surface_usage; /* Free the old surface (and texture if we hold the last @@ -136,12 +136,14 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, /* Probably need dedicated flags for surface usage too: */ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_GPU_WRITE); +#if 0 PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE); +#endif - texture = pipe->screen->texture_create( pipe->screen, - &template ); + strb->texture = pipe->screen->texture_create( pipe->screen, + &template ); /* Special path for accum buffers. * @@ -149,7 +151,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, * only for now, the surface pixel format doesn't really matter, * only that the buffer is large enough. */ - if (!texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) + if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) { /* Actually, just setting this usage value should be sufficient * to tell the driver to go ahead and allocate the buffer, even @@ -159,21 +161,19 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, surface_usage = (PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE); - texture = pipe->screen->texture_create( pipe->screen, - &template ); + strb->texture = pipe->screen->texture_create( pipe->screen, + &template ); } - if (!texture) + if (!strb->texture) return FALSE; strb->surface = pipe->screen->get_tex_surface( pipe->screen, - texture, + strb->texture, 0, 0, 0, surface_usage ); - pipe_texture_reference( &texture, NULL ); - assert(strb->surface->buffer); assert(strb->surface->format); assert(strb->surface->cpp); @@ -195,6 +195,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) struct st_renderbuffer *strb = st_renderbuffer(rb); ASSERT(strb); pipe_surface_reference(&strb->surface, NULL); + pipe_texture_reference(&strb->texture, NULL); free(strb); } @@ -380,6 +381,8 @@ st_render_texture(GLcontext *ctx, rb->Width = pt->width[att->TextureLevel]; rb->Height = pt->height[att->TextureLevel]; + pipe_texture_reference( &strb->texture, pt ); + /* the renderbuffer's surface is inside the texture */ strb->surface = screen->get_tex_surface(screen, pt, att->CubeMapFace, diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index c1aa14f9b22..f9cec913141 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -41,7 +41,8 @@ struct st_renderbuffer { struct gl_renderbuffer Base; - struct pipe_surface *surface; + struct pipe_texture *texture; + struct pipe_surface *surface; /* temporary view into texture */ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ }; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index e242195e7a9..0b2b9d544d7 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -63,10 +63,14 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct gl_framebuffer *fb = ctx->ReadBuffer; struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer); - struct pipe_surface *ps = strb->surface; + struct pipe_surface *ps; ubyte *stmap; GLint j; + /* Create a CPU-READ surface/view into the renderbuffer's texture */ + ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + /* map the stencil buffer */ stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); @@ -126,6 +130,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* unmap the stencil buffer */ screen->surface_unmap(screen, ps); + pipe_surface_reference(&ps, NULL); } @@ -169,12 +174,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLvoid *dest) { struct pipe_context *pipe = ctx->st->pipe; + struct pipe_screen *screen = pipe->screen; GLfloat temp[MAX_WIDTH][4]; const GLbitfield transferOps = ctx->_ImageTransferState; GLint i, yStep, dfStride; GLfloat *df; struct st_renderbuffer *strb; struct gl_pixelstore_attrib clippedPacking = *pack; + struct pipe_surface *surf; /* XXX convolution not done yet */ assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0); @@ -230,6 +237,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, yStep = 1; } + /* Create a CPU-READ surface/view into the renderbuffer's texture */ + surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + /* * Copy pixels from pipe_surface to user memory */ @@ -241,15 +252,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width, format, type); - if (strb->surface->format == PIPE_FORMAT_S8Z24_UNORM || - strb->surface->format == PIPE_FORMAT_X8Z24_UNORM) { + if (surf->format == PIPE_FORMAT_S8Z24_UNORM || + surf->format == PIPE_FORMAT_X8Z24_UNORM) { if (format == GL_DEPTH_COMPONENT) { 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); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); @@ -263,18 +273,18 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* 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); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, dst, 0); y += yStep; dst += dstStride; } } } - else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) { + else if (surf->format == PIPE_FORMAT_Z16_UNORM) { for (i = 0; i < height; i++) { GLushort 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); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -284,12 +294,12 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, dst += dstStride; } } - else if (strb->surface->format == PIPE_FORMAT_Z32_UNORM) { + else if (surf->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); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -303,7 +313,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* 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); + pipe_get_tile_rgba(pipe, surf, x, y, width, 1, df); y += yStep; df += dfStride; if (!dfStride) { @@ -315,6 +325,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } + pipe_surface_reference(&surf, NULL); + _mesa_unmap_readpix_pbo(ctx, &clippedPacking); } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index f6f833a0dbd..828b2340f22 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -306,6 +306,11 @@ guess_and_alloc_texture(struct st_context *st, depth <<= 1; } + if (width == 0 || height == 0 || depth == 0) { + /* no texture needed */ + return; + } + /* Guess a reasonable value for lastLevel. This is probably going * to be wrong fairly often and might mean that we have to look at * resizable buffers, or require that buffers implement lazy @@ -1059,6 +1064,8 @@ fallback_copy_texsubimage(GLcontext *ctx, } src_surf = strb->surface; + src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ, + PIPE_BUFFER_USAGE_CPU_READ); dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -1097,6 +1104,7 @@ fallback_copy_texsubimage(GLcontext *ctx, } screen->tex_surface_release(screen, &dest_surf); + screen->tex_surface_release(screen, &src_surf); } @@ -1164,7 +1172,7 @@ do_copy_texsubimage(GLcontext *ctx, stImage->level, destZ, PIPE_BUFFER_USAGE_CPU_WRITE); - if (ctx->_ImageTransferState == 0x0 && + if (0&& ctx->_ImageTransferState == 0x0 && strb->surface->buffer && dest_surface->buffer) { /* do blit-style copy */