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#include "api_exec_decl.h" 33 34 35/** 36 * Copy a colorbuffer from the window system framebuffer (a window or 37 * pbuffer) to a texture. 38 * This is a helper used by the wglBindTexImageARB() function. 39 * 40 * \param srcBuffer source buffer (GL_FRONT_LEFT, GL_BACK_LEFT, etc) 41 * \param fbWidth width of the source framebuffer 42 * \param fbHeight height of the source framebuffer 43 * \param texTarget which texture target to copy to (GL_TEXTURE_1D/2D/CUBE_MAP) 44 * \param texLevel which texture mipmap level to copy to 45 * \param cubeFace which cube face to copy to (in [0,5]) 46 * \param texFormat what texture format to use, if texture doesn't exist 47 */ 48void 49st_copy_framebuffer_to_texture(GLenum srcBuffer, 50 GLint fbWidth, GLint fbHeight, 51 GLenum texTarget, GLint texLevel, 52 GLuint cubeFace, GLenum texFormat) 53{ 54 GLint readFBOSave, readBufSave, width, height; 55 56 assert(cubeFace < 6); 57 58 /* Save current FBO / readbuffer */ 59 _mesa_GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFBOSave); 60 _mesa_GetIntegerv(GL_READ_BUFFER, &readBufSave); 61 62 /* Read from the winsys buffer */ 63 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); 64 _mesa_ReadBuffer(srcBuffer); 65 66 /* copy image from pbuffer to texture */ 67 switch (texTarget) { 68 case GL_TEXTURE_1D: 69 _mesa_GetTexLevelParameteriv(GL_TEXTURE_1D, texLevel, 70 GL_TEXTURE_WIDTH, &width); 71 if (width == fbWidth) { 72 /* replace existing texture */ 73 _mesa_CopyTexSubImage1D(GL_TEXTURE_1D, 74 texLevel, 75 0, /* xoffset */ 76 0, 0, /* x, y */ 77 fbWidth); 78 } else { 79 /* define initial texture */ 80 _mesa_CopyTexImage1D(GL_TEXTURE_1D, 81 texLevel, 82 texFormat, 83 0, 0, /* x, y */ 84 fbWidth, 0); 85 } 86 break; 87 case GL_TEXTURE_2D: 88 _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel, 89 GL_TEXTURE_WIDTH, &width); 90 _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel, 91 GL_TEXTURE_HEIGHT, &height); 92 if (width == fbWidth && height == fbHeight) { 93 /* replace existing texture */ 94 _mesa_CopyTexSubImage2D(GL_TEXTURE_2D, 95 texLevel, 96 0, 0, /* xoffset, yoffset */ 97 0, 0, /* x, y */ 98 fbWidth, fbHeight); 99 } else { 100 /* define initial texture */ 101 _mesa_CopyTexImage2D(GL_TEXTURE_2D, 102 texLevel, 103 texFormat, 104 0, 0, /* x, y */ 105 fbWidth, fbHeight, 0); 106 } 107 break; 108 case GL_TEXTURE_CUBE_MAP: 109 { 110 const GLenum target = 111 GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace; 112 _mesa_GetTexLevelParameteriv(target, texLevel, 113 GL_TEXTURE_WIDTH, &width); 114 _mesa_GetTexLevelParameteriv(target, texLevel, 115 GL_TEXTURE_HEIGHT, &height); 116 if (width == fbWidth && height == fbHeight) { 117 /* replace existing texture */ 118 _mesa_CopyTexSubImage2D(target, 119 texLevel, 120 0, 0, /* xoffset, yoffset */ 121 0, 0, /* x, y */ 122 fbWidth, fbHeight); 123 } else { 124 /* define new texture */ 125 _mesa_CopyTexImage2D(target, 126 texLevel, 127 texFormat, 128 0, 0, /* x, y */ 129 fbWidth, fbHeight, 0); 130 } 131 } 132 break; 133 default: 134 _mesa_problem(NULL, 135 "unexpected target in st_copy_framebuffer_to_texture()\n"); 136 } 137 138 /* restore readbuffer */ 139 _mesa_ReadBuffer(readBufSave); 140 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, readFBOSave); 141} 142