diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/swrast/s_blit.c | 561 |
1 files changed, 300 insertions, 261 deletions
diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c index b0c56a40fce..043b578a59f 100644 --- a/src/mesa/swrast/s_blit.c +++ b/src/mesa/swrast/s_blit.c @@ -111,6 +111,11 @@ 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; + GLuint i; const GLint srcWidth = ABS(srcX1 - srcX0); const GLint dstWidth = ABS(dstX1 - dstX0); @@ -146,21 +151,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 +175,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 +211,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 (i = 0; i < NumDrawBuffers; i++) { + 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 +513,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); @@ -521,6 +550,7 @@ blit_linear(struct gl_context *ctx, GLubyte *srcMap, *dstMap; GLint srcRowStride, dstRowStride; + GLuint i; /* Determine datatype for resampling */ @@ -556,151 +586,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 (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { + 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); - } } |