summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-05-06 13:47:41 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-05-06 13:48:27 -0600
commit296378b6c8b205048244746e260739448c4ee590 (patch)
tree3c3e53ef0e9f47495ce6281633e1ed1324d31859 /src/mesa/state_tracker
parent973d0c014dba87308e358291de0730d38d50a733 (diff)
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).
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c73
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c33
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c25
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h3
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c34
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c10
6 files changed, 129 insertions, 49 deletions
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index e4ef3e16b7..8098d75e18 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 6ec3c343cd..c967c989de 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 e0578f0b4d..747d4905e6 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 c1aa14f9b2..f9cec91314 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 e242195e7a..0b2b9d544d 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 f6f833a0db..828b2340f2 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 */