101e04c3fSmrg/* 201e04c3fSmrg * Copyright 2015 VMware, Inc. 301e04c3fSmrg * All Rights Reserved. 401e04c3fSmrg * 501e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 601e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 701e04c3fSmrg * to deal in the Software without restriction, including without limitation 801e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 901e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 1001e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1101e04c3fSmrg * 1201e04c3fSmrg * The above copyright notice and this permission notice shall be included 1301e04c3fSmrg * in all copies or substantial portions of the Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1601e04c3fSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 1901e04c3fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2001e04c3fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2101e04c3fSmrg * OTHER DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "main/mtypes.h" 2501e04c3fSmrg#include "main/buffers.h" 2601e04c3fSmrg#include "main/errors.h" 2701e04c3fSmrg#include "main/fbobject.h" 2801e04c3fSmrg#include "main/get.h" 2901e04c3fSmrg#include "main/teximage.h" 3001e04c3fSmrg#include "main/texparam.h" 3101e04c3fSmrg#include "st_copytex.h" 3201e04c3fSmrg 3301e04c3fSmrg 3401e04c3fSmrg/** 3501e04c3fSmrg * Copy a colorbuffer from the window system framebuffer (a window or 3601e04c3fSmrg * pbuffer) to a texture. 3701e04c3fSmrg * This is a helper used by the wglBindTexImageARB() function. 3801e04c3fSmrg * 3901e04c3fSmrg * \param srcBuffer source buffer (GL_FRONT_LEFT, GL_BACK_LEFT, etc) 4001e04c3fSmrg * \param fbWidth width of the source framebuffer 4101e04c3fSmrg * \param fbHeight height of the source framebuffer 4201e04c3fSmrg * \param texTarget which texture target to copy to (GL_TEXTURE_1D/2D/CUBE_MAP) 4301e04c3fSmrg * \param texLevel which texture mipmap level to copy to 4401e04c3fSmrg * \param cubeFace which cube face to copy to (in [0,5]) 4501e04c3fSmrg * \param texFormat what texture format to use, if texture doesn't exist 4601e04c3fSmrg */ 4701e04c3fSmrgvoid 4801e04c3fSmrgst_copy_framebuffer_to_texture(GLenum srcBuffer, 4901e04c3fSmrg GLint fbWidth, GLint fbHeight, 5001e04c3fSmrg GLenum texTarget, GLint texLevel, 5101e04c3fSmrg GLuint cubeFace, GLenum texFormat) 5201e04c3fSmrg{ 5301e04c3fSmrg GLint readFBOSave, readBufSave, width, height; 5401e04c3fSmrg 5501e04c3fSmrg assert(cubeFace < 6); 5601e04c3fSmrg 5701e04c3fSmrg /* Save current FBO / readbuffer */ 5801e04c3fSmrg _mesa_GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFBOSave); 5901e04c3fSmrg _mesa_GetIntegerv(GL_READ_BUFFER, &readBufSave); 6001e04c3fSmrg 6101e04c3fSmrg /* Read from the winsys buffer */ 6201e04c3fSmrg _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); 6301e04c3fSmrg _mesa_ReadBuffer(srcBuffer); 6401e04c3fSmrg 6501e04c3fSmrg /* copy image from pbuffer to texture */ 6601e04c3fSmrg switch (texTarget) { 6701e04c3fSmrg case GL_TEXTURE_1D: 6801e04c3fSmrg _mesa_GetTexLevelParameteriv(GL_TEXTURE_1D, texLevel, 6901e04c3fSmrg GL_TEXTURE_WIDTH, &width); 7001e04c3fSmrg if (width == fbWidth) { 7101e04c3fSmrg /* replace existing texture */ 7201e04c3fSmrg _mesa_CopyTexSubImage1D(GL_TEXTURE_1D, 7301e04c3fSmrg texLevel, 7401e04c3fSmrg 0, /* xoffset */ 7501e04c3fSmrg 0, 0, /* x, y */ 7601e04c3fSmrg fbWidth); 7701e04c3fSmrg } else { 7801e04c3fSmrg /* define initial texture */ 7901e04c3fSmrg _mesa_CopyTexImage1D(GL_TEXTURE_1D, 8001e04c3fSmrg texLevel, 8101e04c3fSmrg texFormat, 8201e04c3fSmrg 0, 0, /* x, y */ 8301e04c3fSmrg fbWidth, 0); 8401e04c3fSmrg } 8501e04c3fSmrg break; 8601e04c3fSmrg case GL_TEXTURE_2D: 8701e04c3fSmrg _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel, 8801e04c3fSmrg GL_TEXTURE_WIDTH, &width); 8901e04c3fSmrg _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel, 9001e04c3fSmrg GL_TEXTURE_HEIGHT, &height); 9101e04c3fSmrg if (width == fbWidth && height == fbHeight) { 9201e04c3fSmrg /* replace existing texture */ 9301e04c3fSmrg _mesa_CopyTexSubImage2D(GL_TEXTURE_2D, 9401e04c3fSmrg texLevel, 9501e04c3fSmrg 0, 0, /* xoffset, yoffset */ 9601e04c3fSmrg 0, 0, /* x, y */ 9701e04c3fSmrg fbWidth, fbHeight); 9801e04c3fSmrg } else { 9901e04c3fSmrg /* define initial texture */ 10001e04c3fSmrg _mesa_CopyTexImage2D(GL_TEXTURE_2D, 10101e04c3fSmrg texLevel, 10201e04c3fSmrg texFormat, 10301e04c3fSmrg 0, 0, /* x, y */ 10401e04c3fSmrg fbWidth, fbHeight, 0); 10501e04c3fSmrg } 10601e04c3fSmrg break; 10701e04c3fSmrg case GL_TEXTURE_CUBE_MAP: 10801e04c3fSmrg { 10901e04c3fSmrg const GLenum target = 11001e04c3fSmrg GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace; 11101e04c3fSmrg _mesa_GetTexLevelParameteriv(target, texLevel, 11201e04c3fSmrg GL_TEXTURE_WIDTH, &width); 11301e04c3fSmrg _mesa_GetTexLevelParameteriv(target, texLevel, 11401e04c3fSmrg GL_TEXTURE_HEIGHT, &height); 11501e04c3fSmrg if (width == fbWidth && height == fbHeight) { 11601e04c3fSmrg /* replace existing texture */ 11701e04c3fSmrg _mesa_CopyTexSubImage2D(target, 11801e04c3fSmrg texLevel, 11901e04c3fSmrg 0, 0, /* xoffset, yoffset */ 12001e04c3fSmrg 0, 0, /* x, y */ 12101e04c3fSmrg fbWidth, fbHeight); 12201e04c3fSmrg } else { 12301e04c3fSmrg /* define new texture */ 12401e04c3fSmrg _mesa_CopyTexImage2D(target, 12501e04c3fSmrg texLevel, 12601e04c3fSmrg texFormat, 12701e04c3fSmrg 0, 0, /* x, y */ 12801e04c3fSmrg fbWidth, fbHeight, 0); 12901e04c3fSmrg } 13001e04c3fSmrg } 13101e04c3fSmrg break; 13201e04c3fSmrg default: 13301e04c3fSmrg _mesa_problem(NULL, 13401e04c3fSmrg "unexpected target in st_copy_framebuffer_to_texture()\n"); 13501e04c3fSmrg } 13601e04c3fSmrg 13701e04c3fSmrg /* restore readbuffer */ 13801e04c3fSmrg _mesa_ReadBuffer(readBufSave); 13901e04c3fSmrg _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, readFBOSave); 14001e04c3fSmrg} 141