1 /* 2 * Copyright 2015 VMware, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included 13 * in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include "main/mtypes.h" 25 #include "main/buffers.h" 26 #include "main/errors.h" 27 #include "main/fbobject.h" 28 #include "main/get.h" 29 #include "main/teximage.h" 30 #include "main/texparam.h" 31 #include "st_copytex.h" 32 33 34 /** 35 * Copy a colorbuffer from the window system framebuffer (a window or 36 * pbuffer) to a texture. 37 * This is a helper used by the wglBindTexImageARB() function. 38 * 39 * \param srcBuffer source buffer (GL_FRONT_LEFT, GL_BACK_LEFT, etc) 40 * \param fbWidth width of the source framebuffer 41 * \param fbHeight height of the source framebuffer 42 * \param texTarget which texture target to copy to (GL_TEXTURE_1D/2D/CUBE_MAP) 43 * \param texLevel which texture mipmap level to copy to 44 * \param cubeFace which cube face to copy to (in [0,5]) 45 * \param texFormat what texture format to use, if texture doesn't exist 46 */ 47 void 48 st_copy_framebuffer_to_texture(GLenum srcBuffer, 49 GLint fbWidth, GLint fbHeight, 50 GLenum texTarget, GLint texLevel, 51 GLuint cubeFace, GLenum texFormat) 52 { 53 GLint readFBOSave, readBufSave, width, height; 54 55 assert(cubeFace < 6); 56 57 /* Save current FBO / readbuffer */ 58 _mesa_GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFBOSave); 59 _mesa_GetIntegerv(GL_READ_BUFFER, &readBufSave); 60 61 /* Read from the winsys buffer */ 62 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); 63 _mesa_ReadBuffer(srcBuffer); 64 65 /* copy image from pbuffer to texture */ 66 switch (texTarget) { 67 case GL_TEXTURE_1D: 68 _mesa_GetTexLevelParameteriv(GL_TEXTURE_1D, texLevel, 69 GL_TEXTURE_WIDTH, &width); 70 if (width == fbWidth) { 71 /* replace existing texture */ 72 _mesa_CopyTexSubImage1D(GL_TEXTURE_1D, 73 texLevel, 74 0, /* xoffset */ 75 0, 0, /* x, y */ 76 fbWidth); 77 } else { 78 /* define initial texture */ 79 _mesa_CopyTexImage1D(GL_TEXTURE_1D, 80 texLevel, 81 texFormat, 82 0, 0, /* x, y */ 83 fbWidth, 0); 84 } 85 break; 86 case GL_TEXTURE_2D: 87 _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel, 88 GL_TEXTURE_WIDTH, &width); 89 _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel, 90 GL_TEXTURE_HEIGHT, &height); 91 if (width == fbWidth && height == fbHeight) { 92 /* replace existing texture */ 93 _mesa_CopyTexSubImage2D(GL_TEXTURE_2D, 94 texLevel, 95 0, 0, /* xoffset, yoffset */ 96 0, 0, /* x, y */ 97 fbWidth, fbHeight); 98 } else { 99 /* define initial texture */ 100 _mesa_CopyTexImage2D(GL_TEXTURE_2D, 101 texLevel, 102 texFormat, 103 0, 0, /* x, y */ 104 fbWidth, fbHeight, 0); 105 } 106 break; 107 case GL_TEXTURE_CUBE_MAP: 108 { 109 const GLenum target = 110 GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace; 111 _mesa_GetTexLevelParameteriv(target, texLevel, 112 GL_TEXTURE_WIDTH, &width); 113 _mesa_GetTexLevelParameteriv(target, texLevel, 114 GL_TEXTURE_HEIGHT, &height); 115 if (width == fbWidth && height == fbHeight) { 116 /* replace existing texture */ 117 _mesa_CopyTexSubImage2D(target, 118 texLevel, 119 0, 0, /* xoffset, yoffset */ 120 0, 0, /* x, y */ 121 fbWidth, fbHeight); 122 } else { 123 /* define new texture */ 124 _mesa_CopyTexImage2D(target, 125 texLevel, 126 texFormat, 127 0, 0, /* x, y */ 128 fbWidth, fbHeight, 0); 129 } 130 } 131 break; 132 default: 133 _mesa_problem(NULL, 134 "unexpected target in st_copy_framebuffer_to_texture()\n"); 135 } 136 137 /* restore readbuffer */ 138 _mesa_ReadBuffer(readBufSave); 139 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, readFBOSave); 140 } 141