st_cb_readpixels.c revision 04ee3cecdf8ef39695bdc66120a4e3bbb9f40aca
1c943dab9a36ac1b48a3da570d44128caa67c9f51Brian/************************************************************************** 2c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * 3c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * All Rights Reserved. 5c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * 6c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * Permission is hereby granted, free of charge, to any person obtaining a 7c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * copy of this software and associated documentation files (the 8c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * "Software"), to deal in the Software without restriction, including 9c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * without limitation the rights to use, copy, modify, merge, publish, 10c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * distribute, sub license, and/or sell copies of the Software, and to 11c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * permit persons to whom the Software is furnished to do so, subject to 12c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * the following conditions: 13c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * 14c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * The above copyright notice and this permission notice (including the 15c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * next paragraph) shall be included in all copies or substantial portions 16c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * of the Software. 17c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * 18c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * 26c943dab9a36ac1b48a3da570d44128caa67c9f51Brian **************************************************************************/ 27c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 28c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 29c943dab9a36ac1b48a3da570d44128caa67c9f51Brian/** 30c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * glReadPixels interface to pipe 31c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * 32c943dab9a36ac1b48a3da570d44128caa67c9f51Brian * \author Brian Paul 33c943dab9a36ac1b48a3da570d44128caa67c9f51Brian */ 34c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 35c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 36c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "main/imports.h" 37c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "main/context.h" 3804ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian#include "main/image.h" 39c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 40c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "pipe/p_context.h" 41c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "pipe/p_defines.h" 42c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "st_context.h" 43c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "st_cb_readpixels.h" 44c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "st_cb_fbo.h" 45c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "st_format.h" 46c943dab9a36ac1b48a3da570d44128caa67c9f51Brian#include "st_public.h" 47c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 48c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 4904ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian/** 5004ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian * Do glReadPixels by getting rows from the framebuffer surface with 5104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian * get_tile(). Convert to requested format/type with Mesa image routines. 5204ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian * Image transfer ops are done in software too. 5304ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian */ 54c943dab9a36ac1b48a3da570d44128caa67c9f51Brianstatic void 55c943dab9a36ac1b48a3da570d44128caa67c9f51Brianst_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, 56c943dab9a36ac1b48a3da570d44128caa67c9f51Brian GLenum format, GLenum type, 5704ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian const struct gl_pixelstore_attrib *pack, 58c943dab9a36ac1b48a3da570d44128caa67c9f51Brian GLvoid *dest) 59c943dab9a36ac1b48a3da570d44128caa67c9f51Brian{ 60c943dab9a36ac1b48a3da570d44128caa67c9f51Brian struct pipe_context *pipe = ctx->st->pipe; 6104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian GLfloat temp[MAX_WIDTH][4]; 6204ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian const GLbitfield transferOps = ctx->_ImageTransferState; 6304ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian GLint i, yInv, dfStride; 6404ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian GLfloat *df; 6504ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian struct st_renderbuffer *strb; 6604ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian struct gl_pixelstore_attrib clippedPacking = *pack; 6704ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 6804ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* XXX convolution not done yet */ 6904ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0); 7004ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 7104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* Do all needed clipping here, so that we can forget about it later */ 7204ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) { 7304ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* The ReadPixels region is totally outside the window bounds */ 7404ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian return; 7504ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian } 7604ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 7704ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 7804ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* XXX check pack->BufferObj !!! */ 7904ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 8004ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 8104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); 8204ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian if (!strb) 8304ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian return; 8404ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 8504ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian pipe->region_map(pipe, strb->surface->region); 86c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 87c943dab9a36ac1b48a3da570d44128caa67c9f51Brian if (format == GL_RGBA && type == GL_FLOAT) { 8804ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* write tile(row) directly into user's buffer */ 8904ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width, 9004ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian height, format, type, 0, 0); 9104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian dfStride = width * 4; 92c943dab9a36ac1b48a3da570d44128caa67c9f51Brian } 93c943dab9a36ac1b48a3da570d44128caa67c9f51Brian else { 9404ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* write tile(row) into temp row buffer */ 9504ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian df = (GLfloat *) temp; 9604ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian dfStride = 0; 97c943dab9a36ac1b48a3da570d44128caa67c9f51Brian } 98c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 9904ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* Do a row at a time to flip image data vertically */ 10004ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian yInv = strb->Base.Height - 1 - y; 10104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian for (i = 0; i < height; i++) { 10204ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian strb->surface->get_tile(strb->surface, x, yInv, width, 1, df); 10304ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian yInv--; 10404ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian df += dfStride; 10504ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian if (!dfStride) { 10604ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian /* convert GLfloat to user's format/type */ 10704ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian GLvoid *dst = _mesa_image_address2d(&clippedPacking, dest, width, 10804ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian height, format, type, i, 0); 10904ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian _mesa_pack_rgba_span_float(ctx, width, temp, format, type, dst, 11004ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian &clippedPacking, transferOps); 11104ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian } 11204ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian } 11304ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 11404ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian pipe->region_unmap(pipe, strb->surface->region); 115c943dab9a36ac1b48a3da570d44128caa67c9f51Brian} 116c943dab9a36ac1b48a3da570d44128caa67c9f51Brian 11704ee3cecdf8ef39695bdc66120a4e3bbb9f40acaBrian 118c943dab9a36ac1b48a3da570d44128caa67c9f51Brianvoid st_init_readpixels_functions(struct dd_function_table *functions) 119c943dab9a36ac1b48a3da570d44128caa67c9f51Brian{ 120c943dab9a36ac1b48a3da570d44128caa67c9f51Brian functions->ReadPixels = st_readpixels; 121c943dab9a36ac1b48a3da570d44128caa67c9f51Brian} 122