On Fri, Dec 21, 2012 at 1:47 PM, Anuj Phogat <anuj.pho...@gmail.com> wrote: > Changes in fbobject.c fix a case when blitting to a framebuffer with > renderbuffers/textures attached to GL_COLOR_ATTACHMENT{i} (where i!=0). > Earlier it skips color blitting if nothing is found attached to > GL_COLOR_ATTACHMENT0. > > Changes in swrast/s_blit.c fix a blitting case when drawAttachment->Texture > == readAttachment->Texture. This caused an assertion failure in > intel_miptree_attach_map() with gles3 conformance test case: > framebuffer_blit_functionality_minifying_blit > Number of changes in this file look scary. But most of them are caused by > introducing a big for loop to support rendering to multiple color > draw buffers. > > V2: Fixed a case when number of draw buffer attachments are zero. > V3: Do compatible_color_datatypes() check for all the draw renderbuffers > in fbobject.c. Put a for loop in blit_nearest() and blit_linear() > functions in swrast/s_blit.c to support blitting to multiple color > draw buffers. > > Signed-off-by: Anuj Phogat <anuj.pho...@gmail.com> > --- > src/mesa/main/fbobject.c | 30 ++- > src/mesa/swrast/s_blit.c | 559 ++++++++++++++++++++++++--------------------- > 2 files changed, 320 insertions(+), 269 deletions(-) > > diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c > index 517bf13..fed0d61 100644 > --- a/src/mesa/main/fbobject.c > +++ b/src/mesa/main/fbobject.c > @@ -2843,8 +2843,10 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint > srcX1, GLint srcY1, > > /* get color read/draw renderbuffers */ > if (mask & GL_COLOR_BUFFER_BIT) { > + const GLuint numColorDrawBuffers = > + ctx->DrawBuffer->_NumColorDrawBuffers; > colorReadRb = readFb->_ColorReadBuffer; > - colorDrawRb = drawFb->_ColorDrawBuffers[0]; > + colorDrawRb = NULL; > > /* From the EXT_framebuffer_object spec: > * > @@ -2852,15 +2854,27 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint > srcX1, GLint srcY1, > * the read and draw framebuffers, the corresponding bit is > silently > * ignored." > */ > - if ((colorReadRb == NULL) || (colorDrawRb == NULL)) { > - colorReadRb = colorDrawRb = NULL; > + if (colorReadRb == NULL) { > mask &= ~GL_COLOR_BUFFER_BIT; > } > - else if (!compatible_color_datatypes(colorReadRb->Format, > - colorDrawRb->Format)) { > - _mesa_error(ctx, GL_INVALID_OPERATION, > - "glBlitFramebufferEXT(color buffer datatypes > mismatch)"); > - return; > + else { > + for (int i = 0; i < numColorDrawBuffers; i++) {
Declaring 'int i' in the loop will not compile with MSVC. And it should probably be unsigned. > + if (ctx->DrawBuffer->_ColorDrawBuffers[i] == NULL) > + continue; > + colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; > + > + if (!compatible_color_datatypes(colorReadRb->Format, > + colorDrawRb->Format)) { > + _mesa_error(ctx, GL_INVALID_OPERATION, > + "glBlitFramebufferEXT(color buffer datatypes > mismatch)"); > + return; > + } > + } > + } > + > + if (colorDrawRb == NULL) { > + colorReadRb = NULL; > + mask &= ~GL_COLOR_BUFFER_BIT; > } > } > else { > diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c > index b0c56a4..4943be9 100644 > --- a/src/mesa/swrast/s_blit.c > +++ b/src/mesa/swrast/s_blit.c > @@ -111,6 +111,10 @@ blit_nearest(struct gl_context *ctx, > GLbitfield buffer) > { > struct gl_renderbuffer *readRb, *drawRb; > + struct gl_renderbuffer_attachment *readAtt, *drawAtt; > + struct gl_framebuffer *readFb = ctx->ReadBuffer; > + struct gl_framebuffer *drawFb = ctx->DrawBuffer; > + GLint NumDrawBuffers = 0; > > const GLint srcWidth = ABS(srcX1 - srcX0); > const GLint dstWidth = ABS(dstX1 - dstX0); > @@ -146,21 +150,16 @@ blit_nearest(struct gl_context *ctx, > > switch (buffer) { > case GL_COLOR_BUFFER_BIT: > - readRb = ctx->ReadBuffer->_ColorReadBuffer; > - drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0]; > - > - if (readRb->Format == drawRb->Format) { > - mode = DIRECT; > - pixelSize = _mesa_get_format_bytes(readRb->Format); > - } else { > - mode = UNPACK_RGBA_FLOAT; > - pixelSize = 16; > - } > - > + readAtt = &readFb->Attachment[readFb->_ColorReadBufferIndex]; > + readRb = readFb->_ColorReadBuffer; > + NumDrawBuffers = drawFb->_NumColorDrawBuffers; > break; > case GL_DEPTH_BUFFER_BIT: > - readRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; > - drawRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; > + readAtt = &readFb->Attachment[BUFFER_DEPTH]; > + drawAtt = &drawFb->Attachment[BUFFER_DEPTH]; > + readRb = readAtt->Renderbuffer; > + drawRb = drawAtt->Renderbuffer; > + NumDrawBuffers = 1; > > /* Note that for depth/stencil, the formats of src/dst must match. By > * using the core helpers for pack/unpack, we avoid needing to handle > @@ -175,8 +174,11 @@ blit_nearest(struct gl_context *ctx, > pixelSize = 4; > break; > case GL_STENCIL_BUFFER_BIT: > - readRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; > - drawRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; > + readAtt = &readFb->Attachment[BUFFER_STENCIL]; > + drawAtt = &drawFb->Attachment[BUFFER_STENCIL]; > + readRb = readAtt->Renderbuffer; > + drawRb = drawAtt->Renderbuffer; > + NumDrawBuffers = 1; > mode = UNPACK_S; > pixelSize = 1; > break; > @@ -208,146 +210,167 @@ blit_nearest(struct gl_context *ctx, > return; > } > > - if (readRb == drawRb) { > - /* map whole buffer for read/write */ > - /* XXX we could be clever and just map the union region of the > - * source and dest rects. > - */ > - GLubyte *map; > - GLint rowStride; > - GLint formatSize = _mesa_get_format_bytes(readRb->Format); > - > - ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, > - readRb->Width, readRb->Height, > - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, > - &map, &rowStride); > - if (!map) { > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > - return; > + /* Blit to all the draw buffers */ > + for (int i = 0; i < NumDrawBuffers; i++) { Another declaration inside a loop. > + if (buffer == GL_COLOR_BUFFER_BIT) { > + int idx = drawFb->_ColorDrawBufferIndexes[i]; > + if (idx == -1) > + continue; > + drawAtt = &drawFb->Attachment[idx]; > + drawRb = drawAtt->Renderbuffer; > + > + if (readRb->Format == drawRb->Format) { > + mode = DIRECT; > + pixelSize = _mesa_get_format_bytes(readRb->Format); > + } else { > + mode = UNPACK_RGBA_FLOAT; > + pixelSize = 16; > + } > } > > - srcMap = map + srcYpos * rowStride + srcXpos * formatSize; > - dstMap = map + dstYpos * rowStride + dstXpos * formatSize; > + if ((readRb == drawRb) || > + (readAtt->Texture && drawAtt->Texture && > + (readAtt->Texture == drawAtt->Texture))) { > + /* map whole buffer for read/write */ > + /* XXX we could be clever and just map the union region of the > + * source and dest rects. > + */ > + GLubyte *map; > + GLint rowStride; > + GLint formatSize = _mesa_get_format_bytes(readRb->Format); > + > + ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, > + readRb->Width, readRb->Height, > + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, > + &map, &rowStride); > + if (!map) { > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + return; > + } > + > + srcMap = map + srcYpos * rowStride + srcXpos * formatSize; > + dstMap = map + dstYpos * rowStride + dstXpos * formatSize; > > - /* this handles overlapping copies */ > - if (srcY0 < dstY0) { > - /* copy in reverse (top->down) order */ > - srcMap += rowStride * (readRb->Height - 1); > - dstMap += rowStride * (readRb->Height - 1); > - srcRowStride = -rowStride; > - dstRowStride = -rowStride; > + /* this handles overlapping copies */ > + if (srcY0 < dstY0) { > + /* copy in reverse (top->down) order */ > + srcMap += rowStride * (readRb->Height - 1); > + dstMap += rowStride * (readRb->Height - 1); > + srcRowStride = -rowStride; > + dstRowStride = -rowStride; > + } > + else { > + /* copy in normal (bottom->up) order */ > + srcRowStride = rowStride; > + dstRowStride = rowStride; > + } > } > else { > - /* copy in normal (bottom->up) order */ > - srcRowStride = rowStride; > - dstRowStride = rowStride; > + /* different src/dst buffers */ > + ctx->Driver.MapRenderbuffer(ctx, readRb, > + srcXpos, srcYpos, > + srcWidth, srcHeight, > + GL_MAP_READ_BIT, &srcMap, > &srcRowStride); > + if (!srcMap) { > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + return; > + } > + ctx->Driver.MapRenderbuffer(ctx, drawRb, > + dstXpos, dstYpos, > + dstWidth, dstHeight, > + GL_MAP_WRITE_BIT, &dstMap, > &dstRowStride); > + if (!dstMap) { > + ctx->Driver.UnmapRenderbuffer(ctx, readRb); > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + return; > + } > } > - } > - else { > - /* different src/dst buffers */ > - ctx->Driver.MapRenderbuffer(ctx, readRb, > - srcXpos, srcYpos, > - srcWidth, srcHeight, > - GL_MAP_READ_BIT, &srcMap, &srcRowStride); > - if (!srcMap) { > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + > + /* allocate the src/dst row buffers */ > + srcBuffer = malloc(pixelSize * srcWidth); > + if (!srcBuffer) { > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); > return; > } > - ctx->Driver.MapRenderbuffer(ctx, drawRb, > - dstXpos, dstYpos, > - dstWidth, dstHeight, > - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); > - if (!dstMap) { > - ctx->Driver.UnmapRenderbuffer(ctx, readRb); > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + dstBuffer = malloc(pixelSize * dstWidth); > + if (!dstBuffer) { > + free(srcBuffer); > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); > return; > } > - } > > - /* allocate the src/dst row buffers */ > - srcBuffer = malloc(pixelSize * srcWidth); > - if (!srcBuffer) { > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); > - return; > - } > - dstBuffer = malloc(pixelSize * dstWidth); > - if (!dstBuffer) { > - free(srcBuffer); > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); > - return; > - } > - > - for (dstRow = 0; dstRow < dstHeight; dstRow++) { > - GLint srcRow = (dstRow * srcHeight) / dstHeight; > - GLubyte *dstRowStart = dstMap + dstRowStride * dstRow; > + for (dstRow = 0; dstRow < dstHeight; dstRow++) { > + GLint srcRow = (dstRow * srcHeight) / dstHeight; > + GLubyte *dstRowStart = dstMap + dstRowStride * dstRow; > > - ASSERT(srcRow >= 0); > - ASSERT(srcRow < srcHeight); > + ASSERT(srcRow >= 0); > + ASSERT(srcRow < srcHeight); > > - if (invertY) { > - srcRow = srcHeight - 1 - srcRow; > - } > + if (invertY) { > + srcRow = srcHeight - 1 - srcRow; > + } > > - /* get pixel row from source and resample to match dest width */ > - if (prevY != srcRow) { > - GLubyte *srcRowStart = srcMap + srcRowStride * srcRow; > - > - switch (mode) { > - case DIRECT: > - memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth); > - break; > - case UNPACK_RGBA_FLOAT: > - _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart, > - srcBuffer); > - break; > - case UNPACK_Z_FLOAT: > - _mesa_unpack_float_z_row(readRb->Format, srcWidth, srcRowStart, > - srcBuffer); > - break; > - case UNPACK_Z_INT: > - _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart, > - srcBuffer); > - break; > - case UNPACK_S: > - _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth, > - srcRowStart, srcBuffer); > - break; > - } > + /* get pixel row from source and resample to match dest width */ > + if (prevY != srcRow) { > + GLubyte *srcRowStart = srcMap + srcRowStride * srcRow; > + > + switch (mode) { > + case DIRECT: > + memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth); > + break; > + case UNPACK_RGBA_FLOAT: > + _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart, > + srcBuffer); > + break; > + case UNPACK_Z_FLOAT: > + _mesa_unpack_float_z_row(readRb->Format, srcWidth, > srcRowStart, > + srcBuffer); > + break; > + case UNPACK_Z_INT: > + _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart, > + srcBuffer); > + break; > + case UNPACK_S: > + _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth, > + srcRowStart, srcBuffer); > + break; > + } > > - (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX); > - prevY = srcRow; > - } > + (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, > invertX); > + prevY = srcRow; > + } > > - /* store pixel row in destination */ > - switch (mode) { > - case DIRECT: > - memcpy(dstRowStart, dstBuffer, pixelSize * srcWidth); > - break; > - case UNPACK_RGBA_FLOAT: > - _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer, > - dstRowStart); > - break; > - case UNPACK_Z_FLOAT: > - _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer, > - dstRowStart); > - break; > - case UNPACK_Z_INT: > - _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer, > - dstRowStart); > - break; > - case UNPACK_S: > - _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer, > - dstRowStart); > - break; > + /* store pixel row in destination */ > + switch (mode) { > + case DIRECT: > + memcpy(dstRowStart, dstBuffer, pixelSize * srcWidth); > + break; > + case UNPACK_RGBA_FLOAT: > + _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer, > + dstRowStart); > + break; > + case UNPACK_Z_FLOAT: > + _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer, > + dstRowStart); > + break; > + case UNPACK_Z_INT: > + _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer, > + dstRowStart); > + break; > + case UNPACK_S: > + _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer, > + dstRowStart); > + break; > + } > } > - } > > - free(srcBuffer); > - free(dstBuffer); > + free(srcBuffer); > + free(dstBuffer); > > - ctx->Driver.UnmapRenderbuffer(ctx, readRb); > - if (drawRb != readRb) { > - ctx->Driver.UnmapRenderbuffer(ctx, drawRb); > + ctx->Driver.UnmapRenderbuffer(ctx, readRb); > + if (drawRb != readRb) { > + ctx->Driver.UnmapRenderbuffer(ctx, drawRb); > + } > } > } > > @@ -489,8 +512,13 @@ blit_linear(struct gl_context *ctx, > GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, > GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) > { > - struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer; > - struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0]; > + struct gl_framebuffer *drawFb = ctx->DrawBuffer; > + struct gl_renderbuffer *drawRb = NULL; > + struct gl_renderbuffer_attachment *drawAtt = NULL; > + struct gl_framebuffer *readFb = ctx->ReadBuffer; > + struct gl_renderbuffer *readRb = readFb->_ColorReadBuffer; > + struct gl_renderbuffer_attachment *readAtt = > + &readFb->Attachment[readFb->_ColorReadBufferIndex]; > > const GLint srcWidth = ABS(srcX1 - srcX0); > const GLint dstWidth = ABS(dstX1 - dstX0); > @@ -556,151 +584,160 @@ blit_linear(struct gl_context *ctx, > return; > } > > - /* > - * Map src / dst renderbuffers > - */ > - if (readRb == drawRb) { > - /* map whole buffer for read/write */ > - ctx->Driver.MapRenderbuffer(ctx, readRb, > - 0, 0, readRb->Width, readRb->Height, > - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, > - &srcMap, &srcRowStride); > - if (!srcMap) { > - free(srcBuffer0); > - free(srcBuffer1); > - free(dstBuffer); > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > - return; > - } > - > - dstMap = srcMap; > - dstRowStride = srcRowStride; > - } > - else { > - /* different src/dst buffers */ > - /* XXX with a bit of work we could just map the regions to be > - * read/written instead of the whole buffers. > + for (int i = 0; i < drawFb->_NumColorDrawBuffers; i++) { Another. > + int idx = drawFb->_ColorDrawBufferIndexes[i]; > + if (idx == -1) > + continue; > + drawAtt = &drawFb->Attachment[idx]; > + drawRb = drawAtt->Renderbuffer; > + /* > + * Map src / dst renderbuffers > */ > - ctx->Driver.MapRenderbuffer(ctx, readRb, > - 0, 0, readRb->Width, readRb->Height, > - GL_MAP_READ_BIT, &srcMap, &srcRowStride); > - if (!srcMap) { > - free(srcBuffer0); > - free(srcBuffer1); > - free(dstBuffer); > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > - return; > + if ((readRb == drawRb) || > + (readAtt->Texture && drawAtt->Texture && > + (readAtt->Texture = drawAtt->Texture))) { > + /* map whole buffer for read/write */ > + ctx->Driver.MapRenderbuffer(ctx, readRb, > + 0, 0, readRb->Width, readRb->Height, > + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, > + &srcMap, &srcRowStride); > + if (!srcMap) { > + free(srcBuffer0); > + free(srcBuffer1); > + free(dstBuffer); > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + return; > + } > + > + dstMap = srcMap; > + dstRowStride = srcRowStride; > } > - ctx->Driver.MapRenderbuffer(ctx, drawRb, > - 0, 0, drawRb->Width, drawRb->Height, > - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); > - if (!dstMap) { > - ctx->Driver.UnmapRenderbuffer(ctx, readRb); > - free(srcBuffer0); > - free(srcBuffer1); > - free(dstBuffer); > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > - return; > + else { > + /* different src/dst buffers */ > + /* XXX with a bit of work we could just map the regions to be > + * read/written instead of the whole buffers. > + */ > + ctx->Driver.MapRenderbuffer(ctx, readRb, > + 0, 0, readRb->Width, readRb->Height, > + GL_MAP_READ_BIT, &srcMap, > &srcRowStride); > + if (!srcMap) { > + free(srcBuffer0); > + free(srcBuffer1); > + free(dstBuffer); > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + return; > + } > + ctx->Driver.MapRenderbuffer(ctx, drawRb, > + 0, 0, drawRb->Width, drawRb->Height, > + GL_MAP_WRITE_BIT, &dstMap, > &dstRowStride); > + if (!dstMap) { > + ctx->Driver.UnmapRenderbuffer(ctx, readRb); > + free(srcBuffer0); > + free(srcBuffer1); > + free(dstBuffer); > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); > + return; > + } > } > - } > > - for (dstRow = 0; dstRow < dstHeight; dstRow++) { > - const GLint dstY = dstYpos + dstRow; > - const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF; > - GLint srcRow0 = IFLOOR(srcRow); > - GLint srcRow1 = srcRow0 + 1; > - GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */ > + for (dstRow = 0; dstRow < dstHeight; dstRow++) { > + const GLint dstY = dstYpos + dstRow; > + const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF; > + GLint srcRow0 = IFLOOR(srcRow); > + GLint srcRow1 = srcRow0 + 1; > + GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow > */ > > - ASSERT(srcRow >= 0); > - ASSERT(srcRow < srcHeight); > + ASSERT(srcRow >= 0); > + ASSERT(srcRow < srcHeight); > > - if (srcRow1 == srcHeight) { > - /* last row fudge */ > - srcRow1 = srcRow0; > - rowWeight = 0.0; > - } > + if (srcRow1 == srcHeight) { > + /* last row fudge */ > + srcRow1 = srcRow0; > + rowWeight = 0.0; > + } > > - if (invertY) { > - srcRow0 = srcHeight - 1 - srcRow0; > - srcRow1 = srcHeight - 1 - srcRow1; > - } > + if (invertY) { > + srcRow0 = srcHeight - 1 - srcRow0; > + srcRow1 = srcHeight - 1 - srcRow1; > + } > > - srcY0 = srcYpos + srcRow0; > - srcY1 = srcYpos + srcRow1; > + srcY0 = srcYpos + srcRow0; > + srcY1 = srcYpos + srcRow1; > > - /* get the two source rows */ > - if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) { > - /* use same source row buffers again */ > - } > - else if (srcY0 == srcBufferY1) { > - /* move buffer1 into buffer0 by swapping pointers */ > - GLvoid *tmp = srcBuffer0; > - srcBuffer0 = srcBuffer1; > - srcBuffer1 = tmp; > - /* get y1 row */ > - { > - GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; > - if (pixelType == GL_UNSIGNED_BYTE) { > - _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, > - src, srcBuffer1); > + /* get the two source rows */ > + if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) { > + /* use same source row buffers again */ > + } > + else if (srcY0 == srcBufferY1) { > + /* move buffer1 into buffer0 by swapping pointers */ > + GLvoid *tmp = srcBuffer0; > + srcBuffer0 = srcBuffer1; > + srcBuffer1 = tmp; > + /* get y1 row */ > + { > + GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; > + if (pixelType == GL_UNSIGNED_BYTE) { > + _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, > + src, srcBuffer1); > + } > + else { > + _mesa_unpack_rgba_row(readFormat, srcWidth, > + src, srcBuffer1); > + } > } > - else { > - _mesa_unpack_rgba_row(readFormat, srcWidth, > - src, srcBuffer1); > + srcBufferY0 = srcY0; > + srcBufferY1 = srcY1; > + } > + else { > + /* get both new rows */ > + { > + GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; > + GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; > + if (pixelType == GL_UNSIGNED_BYTE) { > + _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, > + src0, srcBuffer0); > + _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, > + src1, srcBuffer1); > + } > + else { > + _mesa_unpack_rgba_row(readFormat, srcWidth, src0, > srcBuffer0); > + _mesa_unpack_rgba_row(readFormat, srcWidth, src1, > srcBuffer1); > + } > } > - } > - srcBufferY0 = srcY0; > - srcBufferY1 = srcY1; > - } > - else { > - /* get both new rows */ > + srcBufferY0 = srcY0; > + srcBufferY1 = srcY1; > + } > + > + if (pixelType == GL_UNSIGNED_BYTE) { > + resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, > srcBuffer1, > + dstBuffer, invertX, rowWeight); > + } > + else { > + resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, > srcBuffer1, > + dstBuffer, invertX, rowWeight); > + } > + > + /* store pixel row in destination */ > { > - GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; > - GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; > + GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; > if (pixelType == GL_UNSIGNED_BYTE) { > - _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, > - src0, srcBuffer0); > - _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, > - src1, srcBuffer1); > + _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, > dst); > } > else { > - _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0); > - _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1); > + _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, > dst); > } > } > - srcBufferY0 = srcY0; > - srcBufferY1 = srcY1; > } > > - if (pixelType == GL_UNSIGNED_BYTE) { > - resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1, > - dstBuffer, invertX, rowWeight); > - } > - else { > - resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, > srcBuffer1, > - dstBuffer, invertX, rowWeight); > - } > + free(srcBuffer0); > + free(srcBuffer1); > + free(dstBuffer); > > - /* store pixel row in destination */ > - { > - GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; > - if (pixelType == GL_UNSIGNED_BYTE) { > - _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst); > - } > - else { > - _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst); > - } > + ctx->Driver.UnmapRenderbuffer(ctx, readRb); > + if (drawRb != readRb) { > + ctx->Driver.UnmapRenderbuffer(ctx, drawRb); > } > } > - > - free(srcBuffer0); > - free(srcBuffer1); > - free(dstBuffer); > - > - ctx->Driver.UnmapRenderbuffer(ctx, readRb); > - if (drawRb != readRb) { > - ctx->Driver.UnmapRenderbuffer(ctx, drawRb); > - } > } > > > -- > 1.7.7.6 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev