[Mesa-dev] [V3 PATCH 6/6] mesa: Add support to allow blitting to multiple color draw buffers
Brian Paul
brian.e.paul at gmail.com
Fri Dec 21 13:00:34 PST 2012
On Fri, Dec 21, 2012 at 1:47 PM, Anuj Phogat <anuj.phogat at 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.phogat at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list