meta.c revision 0fc11a24c85413a335b87bc34659d2381fd6670c
1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* 2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Mesa 3-D graphics library 3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Version: 7.6 4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Permission is hereby granted, free of charge, to any person obtaining a 8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * copy of this software and associated documentation files (the "Software"), 9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * to deal in the Software without restriction, including without limitation 10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * and/or sell copies of the Software, and to permit persons to whom the 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Software is furnished to do so, subject to the following conditions: 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * The above copyright notice and this permission notice shall be included 15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * in all copies or substantial portions of the Software. 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Meta operations. Some GL operations can be expressed in terms of 275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * other GL operations. For example, glBlitFramebuffer() can be done 28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * with texture mapping and glClear() can be done with polygon rendering. 29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * \author Brian Paul 315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang */ 325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/glheader.h" 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/mtypes.h" 36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/imports.h" 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/arbprogram.h" 38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/arrayobj.h" 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/blend.h" 40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/bufferobj.h" 41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/buffers.h" 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/colortab.h" 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/condrender.h" 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/depth.h" 45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/enable.h" 46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/fbobject.h" 47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/feedback.h" 48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/formats.h" 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/glformats.h" 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/image.h" 51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/macros.h" 52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/matrix.h" 53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/mipmap.h" 54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/pixel.h" 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/pbo.h" 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/polygon.h" 57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/readpix.h" 58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/scissor.h" 59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/shaderapi.h" 60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/shaderobj.h" 61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/state.h" 62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/stencil.h" 635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/texobj.h" 645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/texenv.h" 655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/texgetimage.h" 665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/teximage.h" 67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/texparam.h" 68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/texstate.h" 69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/transformfeedback.h" 70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/uniforms.h" 71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/varray.h" 72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/viewport.h" 735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/samplerobj.h" 74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "program/program.h" 75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "swrast/swrast.h" 76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "drivers/common/meta.h" 775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "main/enums.h" 78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "main/glformats.h" 79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** Return offset in bytes of the field within a vertex struct */ 82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD)) 83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State which we may save/restore across meta ops. 86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * XXX this may be incomplete... 87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct save_state 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLbitfield SavedState; /**< bitmask of MESA_META_* flags */ 91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_ALPHA_TEST */ 93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean AlphaEnabled; 94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum AlphaFunc; 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLclampf AlphaRef; 96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_BLEND */ 98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLbitfield BlendEnabled; 99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLboolean ColorLogicOpEnabled; 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_COLOR_MASK */ 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_DEPTH_TEST */ 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_depthbuffer_attrib Depth; 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_FOG */ 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean Fog; 109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_PIXEL_STORE */ 111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_pixelstore_attrib Pack, Unpack; 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_PIXEL_TRANSFER */ 114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat RedBias, RedScale; 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat GreenBias, GreenScale; 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat BlueBias, BlueScale; 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat AlphaBias, AlphaScale; 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat DepthBias, DepthScale; 1195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLboolean MapColorFlag; 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_RASTERIZATION */ 122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum FrontPolygonMode, BackPolygonMode; 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean PolygonOffset; 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean PolygonSmooth; 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean PolygonStipple; 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean PolygonCull; 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_SCISSOR */ 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_scissor_attrib Scissor; 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_SHADER */ 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean VertexProgramEnabled; 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_vertex_program *VertexProgram; 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean FragmentProgramEnabled; 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_fragment_program *FragmentProgram; 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct gl_shader_program *VertexShader; 137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_shader_program *GeometryShader; 1385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang struct gl_shader_program *FragmentShader; 1395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang struct gl_shader_program *ActiveShader; 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_STENCIL_TEST */ 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_stencil_attrib Stencil; 1435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_TRANSFORM */ 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum MatrixMode; 146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat ModelviewMatrix[16]; 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat ProjectionMatrix[16]; 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat TextureMatrix[16]; 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_CLIP */ 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLbitfield ClipPlanesEnabled; 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_TEXTURE */ 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ActiveUnit; 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ClientActiveUnit; 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** for unit[0] only */ 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS]; 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** mask of TEXTURE_2D_BIT, etc */ 159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLbitfield TexEnabled[MAX_TEXTURE_UNITS]; 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS]; 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint EnvMode; /* unit[0] only */ 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_VERTEX */ 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_array_object *ArrayObj; 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_buffer_object *ArrayBufferObj; 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_VIEWPORT */ 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLint ViewportX, ViewportY, ViewportW, ViewportH; 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLclampd DepthNear, DepthFar; 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_CLAMP_FRAGMENT_COLOR */ 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum ClampFragmentColor; 173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_CLAMP_VERTEX_COLOR */ 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum ClampVertexColor; 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /** MESA_META_CONDITIONAL_RENDER */ 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_query_object *CondRenderQuery; 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum CondRenderMode; 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if FEATURE_feedback 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_SELECT_FEEDBACK */ 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum RenderMode; 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_selection Select; 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gl_feedback Feedback; 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** MESA_META_MULTISAMPLE */ 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean MultisampleEnabled; 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** Miscellaneous (always disabled) */ 192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean Lighting; 193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean RasterDiscard; 194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if FEATURE_EXT_transform_feedback 195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean TransformFeedbackNeedsResume; 196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc. 201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * This is currently shared by all the meta ops. But we could create a 202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc. 203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 2045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstruct temp_texture 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint TexObj; 207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */ 208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLsizei MinSize; /**< Min texture size to allocate */ 209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLsizei MaxSize; /**< Max possible texture size */ 210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean NPOT; /**< Non-power of two size OK? */ 211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLsizei Width, Height; /**< Current texture size */ 212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLenum IntFormat; 213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat Sright, Ttop; /**< right, top texcoords */ 214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for glBlitFramebufer() 219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct blit_state 221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 2235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLuint VBO; 2245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLuint DepthFP; 225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang/** 229f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * State for glClear() 230f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang */ 231f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstruct clear_state 232f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang{ 233f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang GLuint ArrayObj; 234f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang GLuint VBO; 235f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang GLuint ShaderProg; 236f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang GLint ColorLocation; 2375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 238f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang GLuint IntegerShaderProg; 239f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang GLint IntegerColorLocation; 240f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang}; 241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for glCopyPixels() 245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct copypix_state 247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint VBO; 250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for glDrawPixels() 255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct drawpix_state 257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint StencilFP; /**< Fragment program for drawing stencil images */ 261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint DepthFP; /**< Fragment program for drawing depth images */ 262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for glBitmap() 267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct bitmap_state 269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint VBO; 272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct temp_texture Tex; /**< separate texture from other meta ops */ 273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for _mesa_meta_generate_mipmap() 278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct gen_mipmap_state 280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint VBO; 2835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLuint FBO; 2845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLuint Sampler; 285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ShaderProg; 286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLuint IntegerShaderProg; 287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}; 288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for texture decompression 292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct decompress_state 294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint VBO, FBO, RBO, Sampler; 297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLint Width, Height; 298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * State for glDrawTex() 302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct drawtex_state 304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint ArrayObj; 306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint VBO; 307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define MAX_META_OPS_DEPTH 8 3105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang/** 3115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * All per-context meta state. 312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct gl_meta_state 314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** Stack of state saved during meta-ops */ 316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct save_state Save[MAX_META_OPS_DEPTH]; 317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /** Save stack depth */ 318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint SaveStackDepth; 319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct temp_texture TempTex; 321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */ 323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct clear_state Clear; /**< For _mesa_meta_Clear() */ 324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */ 325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */ 326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */ 327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */ 328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct decompress_state Decompress; /**< For texture decompression */ 329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */ 330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit); 333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex); 334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear); 335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, 336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct gen_mipmap_state *mipmap); 337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic GLuint 339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangcompile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source) 340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint shader; 342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLint ok, size; 343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLchar *info; 344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang shader = _mesa_CreateShaderObjectARB(target); 346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ShaderSourceARB(shader, 1, &source, NULL); 347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_CompileShaderARB(shader); 348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok); 350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ok) 351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return shader; 352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); 354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (size == 0) { 355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DeleteObjectARB(shader); 356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang info = malloc(size); 360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!info) { 361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DeleteObjectARB(shader); 362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GetProgramInfoLog(shader, size, NULL, info); 366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_problem(ctx, 367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "meta program compile failed:\n%s\n" 368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "source:\n%s\n", 369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang info, source); 370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang free(info); 372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DeleteObjectARB(shader); 373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic GLuint 378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuanglink_program_with_debug(struct gl_context *ctx, GLuint program) 379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLint ok, size; 381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLchar *info; 382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LinkProgramARB(program); 384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok); 386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ok) 387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return program; 388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size); 390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (size == 0) 391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 392b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 393b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info = malloc(size); 394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!info) 395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GetProgramInfoLog(program, size, NULL, info); 3985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_problem(ctx, "meta program link failed:\n%s", info); 3995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang free(info); 401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Initialize meta-ops for a context. 407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * To be called once during context creation. 408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid 410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_mesa_meta_init(struct gl_context *ctx) 411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT(!ctx->Meta); 413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Meta = CALLOC_STRUCT(gl_meta_state); 415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 4195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * Free context meta-op state. 4205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * To be called once during context destruction. 4215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang */ 422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid 423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_mesa_meta_free(struct gl_context *ctx) 4245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang{ 42591037db265ecdd914a26e056cf69207b4f50924ehkuang GET_CURRENT_CONTEXT(old_context); 426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_make_current(ctx, NULL, NULL); 427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit); 428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear); 429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap); 430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cleanup_temp_texture(ctx, &ctx->Meta->TempTex); 431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (old_context) 432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); 433b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else 434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_make_current(NULL, NULL, NULL); 435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang free(ctx->Meta); 436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Meta = NULL; 437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Enter meta state. This is like a light-weight version of glPushAttrib 442b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * but it also resets most GL state back to default values. 443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 4445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * \param state bitmask of MESA_META_* flags indicating which attribute groups 4455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * to save and reset to their defaults 446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid 448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_mesa_meta_begin(struct gl_context *ctx, GLbitfield state) 449b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct save_state *save; 451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* hope MAX_META_OPS_DEPTH is large enough */ 453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH); 454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++]; 456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memset(save, 0, sizeof(*save)); 457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->SavedState = state; 458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if FEATURE_EXT_transform_feedback 460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Pausing transform feedback needs to be done early, or else we won't be 461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * able to change other state. 462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->TransformFeedbackNeedsResume = 464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->TransformFeedback.CurrentObject->Active && 465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang !ctx->TransformFeedback.CurrentObject->Paused; 466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->TransformFeedbackNeedsResume) 467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_PauseTransformFeedback(); 468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_ALPHA_TEST) { 471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->AlphaEnabled = ctx->Color.AlphaEnabled; 472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->AlphaFunc = ctx->Color.AlphaFunc; 473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->AlphaRef = ctx->Color.AlphaRef; 474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.AlphaEnabled) 475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE); 476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_BLEND) { 479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->BlendEnabled = ctx->Color.BlendEnabled; 480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.BlendEnabled) { 481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.EXT_draw_buffers2) { 482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint i; 483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE); 485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_BLEND, GL_FALSE); 489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled; 492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.ColorLogicOpEnabled) 493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE); 494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_COLOR_MASK) { 497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memcpy(save->ColorMask, ctx->Color.ColorMask, 498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sizeof(ctx->Color.ColorMask)); 499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ctx->Color.ColorMask[0][0] || 500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang !ctx->Color.ColorMask[0][1] || 501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang !ctx->Color.ColorMask[0][2] || 502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang !ctx->Color.ColorMask[0][3]) 503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_DEPTH_TEST) { 507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Depth = ctx->Depth; /* struct copy */ 508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Depth.Test) 509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); 510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_FOG) { 513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Fog = ctx->Fog.Enabled; 514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Fog.Enabled) 515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_FOG, GL_FALSE); 516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_PIXEL_STORE) { 519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Pack = ctx->Pack; 520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Unpack = ctx->Unpack; 521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pack = ctx->DefaultPacking; 522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Unpack = ctx->DefaultPacking; 523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 52591037db265ecdd914a26e056cf69207b4f50924ehkuang if (state & MESA_META_PIXEL_TRANSFER) { 526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->RedScale = ctx->Pixel.RedScale; 527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->RedBias = ctx->Pixel.RedBias; 528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->GreenScale = ctx->Pixel.GreenScale; 529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->GreenBias = ctx->Pixel.GreenBias; 530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->BlueScale = ctx->Pixel.BlueScale; 531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->BlueBias = ctx->Pixel.BlueBias; 532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->AlphaScale = ctx->Pixel.AlphaScale; 533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->AlphaBias = ctx->Pixel.AlphaBias; 534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->MapColorFlag = ctx->Pixel.MapColorFlag; 535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.RedScale = 1.0F; 536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.RedBias = 0.0F; 537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.GreenScale = 1.0F; 538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.GreenBias = 0.0F; 539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.BlueScale = 1.0F; 540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.BlueBias = 0.0F; 541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.AlphaScale = 1.0F; 542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.AlphaBias = 0.0F; 543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.MapColorFlag = GL_FALSE; 544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* XXX more state */ 545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->NewState |=_NEW_PIXEL; 546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_RASTERIZATION) { 549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->FrontPolygonMode = ctx->Polygon.FrontMode; 550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->BackPolygonMode = ctx->Polygon.BackMode; 551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->PolygonOffset = ctx->Polygon.OffsetFill; 552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->PolygonSmooth = ctx->Polygon.SmoothFlag; 553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->PolygonStipple = ctx->Polygon.StippleFlag; 554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->PolygonCull = ctx->Polygon.CullFlag; 555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); 556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE); 557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE); 558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE); 559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE); 560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_SCISSOR) { 563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Scissor = ctx->Scissor; /* struct copy */ 564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE); 565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_SHADER) { 568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_vertex_program) { 569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->VertexProgramEnabled = ctx->VertexProgram.Enabled; 570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_vertprog(ctx, &save->VertexProgram, 571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->VertexProgram.Current); 572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE); 573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_fragment_program) { 576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled; 577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_fragprog(ctx, &save->FragmentProgram, 578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->FragmentProgram.Current); 579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE); 580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_shader_objects) { 583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->VertexShader, 584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Shader.CurrentVertexProgram); 585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->GeometryShader, 586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Shader.CurrentGeometryProgram); 587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->FragmentShader, 588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Shader.CurrentFragmentProgram); 589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->ActiveShader, 590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Shader.ActiveProgram); 591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_UseProgramObjectARB(0); 593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_STENCIL_TEST) { 597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Stencil = ctx->Stencil; /* struct copy */ 598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Stencil.Enabled) 599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE); 600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* NOTE: other stencil state not reset */ 601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_TEXTURE) { 604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint u, tgt; 605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ActiveUnit = ctx->Texture.CurrentUnit; 607ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ClientActiveUnit = ctx->Array.ActiveTexture; 608ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->EnvMode = ctx->Texture.Unit[0].EnvMode; 609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Disable all texture units */ 611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled; 613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled; 6145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (ctx->Texture.Unit[u].Enabled || 615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Texture.Unit[u].TexGenEnabled) { 616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0 + u); 617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE); 618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE); 619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE); 620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_texture_cube_map) 621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); 622b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ctx->Extensions.NV_texture_rectangle) 623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE); 624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.OES_EGL_image_external) 625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_EXTERNAL_OES, GL_FALSE); 626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE); 627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE); 628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE); 629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE); 630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 631b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 6335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* save current texture objects for unit[0] only */ 6345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_texobj(&save->CurrentTexture[tgt], 636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Texture.Unit[0].CurrentTex[tgt]); 637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 638b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* set defaults for unit[0] */ 640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0); 641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClientActiveTextureARB(GL_TEXTURE0); 642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_TRANSFORM) { 646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint activeTexture = ctx->Texture.CurrentUnit; 647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m, 648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 16 * sizeof(GLfloat)); 649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m, 650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 16 * sizeof(GLfloat)); 651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m, 652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 16 * sizeof(GLfloat)); 653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->MatrixMode = ctx->Transform.MatrixMode; 654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* set 1:1 vertex:pixel coordinate transform */ 655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0); 656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(GL_TEXTURE); 657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LoadIdentity(); 658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture); 659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(GL_MODELVIEW); 660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LoadIdentity(); 661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(GL_PROJECTION); 662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LoadIdentity(); 663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_Ortho(0.0, ctx->DrawBuffer->Width, 664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 0.0, ctx->DrawBuffer->Height, 665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang -1.0, 1.0); 666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CLIP) { 669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled; 670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Transform.ClipPlanesEnabled) { 671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint i; 672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { 673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); 674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_VERTEX) { 679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* save vertex array object state */ 680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_array_object(ctx, &save->ArrayObj, 681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Array.ArrayObj); 682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, 683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Array.ArrayBufferObj); 684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* set some default state? */ 685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_VIEWPORT) { 688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* save viewport state */ 689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportX = ctx->Viewport.X; 690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportY = ctx->Viewport.Y; 691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportW = ctx->Viewport.Width; 692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportH = ctx->Viewport.Height; 693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* set viewport to match window size */ 694ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Viewport.X != 0 || 695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Viewport.Y != 0 || 696ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Viewport.Width != ctx->DrawBuffer->Width || 697ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Viewport.Height != ctx->DrawBuffer->Height) { 698ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_viewport(ctx, 0, 0, 699ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); 700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 701ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* save depth range state */ 702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->DepthNear = ctx->Viewport.Near; 703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->DepthFar = ctx->Viewport.Far; 704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* set depth range to default */ 705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DepthRange(0.0, 1.0); 706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { 709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ClampFragmentColor = ctx->Color.ClampFragmentColor; 710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Generally in here we want to do clamping according to whether 712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * it's for the pixel path (ClampFragmentColor is GL_TRUE), 713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * regardless of the internal implementation of the metaops. 714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.ClampFragmentColor != GL_TRUE) 716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CLAMP_VERTEX_COLOR) { 720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ClampVertexColor = ctx->Light.ClampVertexColor; 721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Generally in here we never want vertex color clamping -- 723ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * result clamping is only dependent on fragment clamping. 724ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE); 726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CONDITIONAL_RENDER) { 729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->CondRenderQuery = ctx->Query.CondRenderQuery; 730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->CondRenderMode = ctx->Query.CondRenderMode; 731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Query.CondRenderQuery) 733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_EndConditionalRender(); 734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if FEATURE_feedback 737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_SELECT_FEEDBACK) { 738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->RenderMode = ctx->RenderMode; 739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->RenderMode == GL_SELECT) { 740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Select = ctx->Select; /* struct copy */ 741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_RenderMode(GL_RENDER); 742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else if (ctx->RenderMode == GL_FEEDBACK) { 743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Feedback = ctx->Feedback; /* struct copy */ 744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_RenderMode(GL_RENDER); 745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_MULTISAMPLE) { 750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->MultisampleEnabled = ctx->Multisample.Enabled; 751ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Multisample.Enabled) 752ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_MULTISAMPLE, GL_FALSE); 753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* misc */ 756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang { 757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Lighting = ctx->Light.Enabled; 758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Light.Enabled) 759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE); 760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->RasterDiscard = ctx->RasterDiscard; 761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->RasterDiscard) 762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE); 763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 767ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 768ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Leave meta state. This is like a light-weight version of glPopAttrib(). 769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid 771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_mesa_meta_end(struct gl_context *ctx) 772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth]; 774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const GLbitfield state = save->SavedState; 775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_ALPHA_TEST) { 777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.AlphaEnabled != save->AlphaEnabled) 778ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled); 779ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef); 780ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 781ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_BLEND) { 783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.BlendEnabled != save->BlendEnabled) { 784ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.EXT_draw_buffers2) { 785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint i; 786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1); 788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1)); 792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) 795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); 796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_COLOR_MASK) { 799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint i; 800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) { 802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (i == 0) { 803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1], 804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ColorMask[i][2], save->ColorMask[i][3]); 805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 806ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ColorMaskIndexed(i, 808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ColorMask[i][0], 809ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ColorMask[i][1], 810b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian save->ColorMask[i][2], 811b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian save->ColorMask[i][3]); 812b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 813b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 8165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 8175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (state & MESA_META_DEPTH_TEST) { 818ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Depth.Test != save->Depth.Test) 819ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test); 820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DepthFunc(save->Depth.Func); 821ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DepthMask(save->Depth.Mask); 822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 823ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 824ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_FOG) { 825ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_FOG, save->Fog); 826ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 827ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 828ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_PIXEL_STORE) { 829ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pack = save->Pack; 830ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Unpack = save->Unpack; 831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_PIXEL_TRANSFER) { 834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.RedScale = save->RedScale; 835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.RedBias = save->RedBias; 836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.GreenScale = save->GreenScale; 8375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang ctx->Pixel.GreenBias = save->GreenBias; 838b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->Pixel.BlueScale = save->BlueScale; 839b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->Pixel.BlueBias = save->BlueBias; 840ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.AlphaScale = save->AlphaScale; 841ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Pixel.AlphaBias = save->AlphaBias; 8425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang ctx->Pixel.MapColorFlag = save->MapColorFlag; 84391037db265ecdd914a26e056cf69207b4f50924ehkuang /* XXX more state */ 844ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->NewState |=_NEW_PIXEL; 845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_RASTERIZATION) { 84891037db265ecdd914a26e056cf69207b4f50924ehkuang _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); 84991037db265ecdd914a26e056cf69207b4f50924ehkuang _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); 850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple); 851b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset); 852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth); 853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull); 854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 855ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_SCISSOR) { 857ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled); 858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_Scissor(save->Scissor.X, save->Scissor.Y, 859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->Scissor.Width, save->Scissor.Height); 860b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 8625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (state & MESA_META_SHADER) { 8635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (ctx->Extensions.ARB_vertex_program) { 864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, 865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->VertexProgramEnabled); 866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, 8675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang save->VertexProgram); 868f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL); 869f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang } 870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_fragment_program) { 872f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, 873f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang save->FragmentProgramEnabled); 874f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, 875f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang save->FragmentProgram); 8765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL); 877f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang } 878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_vertex_shader) 880b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader); 881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_geometry_shader4) 883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, 884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->GeometryShader); 885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.ARB_fragment_shader) 887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, 888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->FragmentShader); 889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, 891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ActiveShader); 892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->VertexShader, NULL); 894ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->GeometryShader, NULL); 895ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->FragmentShader, NULL); 896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL); 897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_STENCIL_TEST) { 900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const struct gl_stencil_attrib *stencil = &save->Stencil; 901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); 903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClearStencil(stencil->Clear); 904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.EXT_stencil_two_side) { 905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, 906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->TestTwoSide); 907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveStencilFaceEXT(stencil->ActiveFace 908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ? GL_BACK : GL_FRONT); 909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* front state */ 911ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_StencilFuncSeparate(GL_FRONT, 912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->Function[0], 913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->Ref[0], 914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->ValueMask[0]); 915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); 916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], 917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->ZFailFunc[0], 918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->ZPassFunc[0]); 919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* back state */ 920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_StencilFuncSeparate(GL_BACK, 921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->Function[1], 922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->Ref[1], 923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->ValueMask[1]); 924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); 925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], 926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->ZFailFunc[1], 927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stencil->ZPassFunc[1]); 928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 930ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_TEXTURE) { 931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint u, tgt; 932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT(ctx->Texture.CurrentUnit == 0); 934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* restore texenv for unit[0] */ 936ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode); 937ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 938ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* restore texture objects for unit[0] only */ 939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 940ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Texture.Unit[0].CurrentTex[tgt] != save->CurrentTexture[tgt]) { 941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FLUSH_VERTICES(ctx, _NEW_TEXTURE); 942ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt], 943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->CurrentTexture[tgt]); 944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL); 946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Restore fixed function texture enables, texgen */ 949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Texture.Unit[u].Enabled != save->TexEnabled[u]) { 951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FLUSH_VERTICES(ctx, _NEW_TEXTURE); 952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Texture.Unit[u].Enabled = save->TexEnabled[u]; 953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Texture.Unit[u].TexGenEnabled != save->TexGenEnabled[u]) { 956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FLUSH_VERTICES(ctx, _NEW_TEXTURE); 957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Texture.Unit[u].TexGenEnabled = save->TexGenEnabled[u]; 958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 960ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 961ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* restore current unit state */ 962ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit); 963ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit); 964ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 965ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 966ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_TRANSFORM) { 967ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint activeTexture = ctx->Texture.CurrentUnit; 968ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0); 969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(GL_TEXTURE); 970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LoadMatrixf(save->TextureMatrix); 971ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture); 972ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 973ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(GL_MODELVIEW); 974ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LoadMatrixf(save->ModelviewMatrix); 975ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(GL_PROJECTION); 977ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_LoadMatrixf(save->ProjectionMatrix); 978ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 979ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_MatrixMode(save->MatrixMode); 980ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 981ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 982ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CLIP) { 983ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->ClipPlanesEnabled) { 984ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLuint i; 985ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { 986ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->ClipPlanesEnabled & (1 << i)) { 987ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); 988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 989ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 990ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 991ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 992ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 993ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_VERTEX) { 994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* restore vertex buffer object */ 995ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name); 996ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL); 997ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 998ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* restore vertex array object */ 999ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_BindVertexArray(save->ArrayObj->Name); 1000ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_reference_array_object(ctx, &save->ArrayObj, NULL); 1001ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1002ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_VIEWPORT) { 1004ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->ViewportX != ctx->Viewport.X || 1005ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportY != ctx->Viewport.Y || 1006ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportW != ctx->Viewport.Width || 1007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportH != ctx->Viewport.Height) { 1008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY, 1009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->ViewportW, save->ViewportH); 1010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DepthRange(save->DepthNear, save->DepthFar); 1012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { 1015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor); 1016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1018ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CLAMP_VERTEX_COLOR) { 1019ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor); 1020ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_CONDITIONAL_RENDER) { 1023ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->CondRenderQuery) 1024ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_BeginConditionalRender(save->CondRenderQuery->Id, 1025ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang save->CondRenderMode); 1026ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1027ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1028ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if FEATURE_feedback 1029ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_SELECT_FEEDBACK) { 1030ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->RenderMode == GL_SELECT) { 1031ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_RenderMode(GL_SELECT); 1032ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Select = save->Select; 1033ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else if (save->RenderMode == GL_FEEDBACK) { 1034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_RenderMode(GL_FEEDBACK); 1035ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ctx->Feedback = save->Feedback; 1036ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1038ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 1039ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1040ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (state & MESA_META_MULTISAMPLE) { 1041ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Multisample.Enabled != save->MultisampleEnabled) 1042ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_MULTISAMPLE, save->MultisampleEnabled); 1043ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1044ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1045ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* misc */ 1046ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->Lighting) { 1047ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); 1048ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->RasterDiscard) { 1050ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE); 1051ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1052ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if FEATURE_EXT_transform_feedback 1053ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (save->TransformFeedbackNeedsResume) 1054ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_ResumeTransformFeedback(); 1055ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 1056ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1057ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1058ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1059ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1060ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Determine whether Mesa is currently in a meta state. 1061ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1062ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangGLboolean 1063ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_mesa_meta_in_progress(struct gl_context *ctx) 1064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1065ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ctx->Meta->SaveStackDepth != 0; 1066ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1067ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1070ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Convert Z from a normalized value in the range [0, 1] to an object-space 1071ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Z coordinate in [-1, +1] so that drawing at the new Z position with the 1072ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * default/identity ortho projection results in the original Z value. 1073ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z 1074ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * value comes from the clear value or raster position. 1075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1076ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic INLINE GLfloat 1077ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuanginvert_z(GLfloat normZ) 1078ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1079ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLfloat objZ = 1.0f - 2.0f * normZ; 1080ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return objZ; 1081ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1082ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1083ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1084ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1085ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * One-time init for a temp_texture object. 1086ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Choose tex target, compute max tex size, etc. 1087ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1088ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void 1089ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuanginit_temp_texture(struct gl_context *ctx, struct temp_texture *tex) 1090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1091ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* prefer texture rectangle */ 1092ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ctx->Extensions.NV_texture_rectangle) { 1093ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Target = GL_TEXTURE_RECTANGLE; 1094ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->MaxSize = ctx->Const.MaxTextureRectSize; 1095ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->NPOT = GL_TRUE; 1096ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1097ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 1098ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* use 2D texture, NPOT if possible */ 1099ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Target = GL_TEXTURE_2D; 1100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two; 1102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->MinSize = 16; /* 16 x 16 at least */ 1104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert(tex->MaxSize > 0); 1105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_GenTextures(1, &tex->TexObj); 1107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void 1110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangcleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex) 1111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!tex->TexObj) 1113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return; 1114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_DeleteTextures(1, &tex->TexObj); 1115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->TexObj = 0; 1116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Return pointer to temp_texture info for non-bitmap ops. 1121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * This does some one-time init if needed. 1122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic struct temp_texture * 1124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangget_temp_texture(struct gl_context *ctx) 1125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct temp_texture *tex = &ctx->Meta->TempTex; 1127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!tex->TexObj) { 1129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang init_temp_texture(ctx, tex); 1130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return tex; 1133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Return pointer to temp_texture info for _mesa_meta_bitmap(). 1138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * We use a separate texture for bitmaps to reduce texture 1139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * allocation/deallocation. 1140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic struct temp_texture * 1142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangget_bitmap_temp_texture(struct gl_context *ctx) 1143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct temp_texture *tex = &ctx->Meta->Bitmap.Tex; 1145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!tex->TexObj) { 1147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang init_temp_texture(ctx, tex); 1148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return tex; 1151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Compute the width/height of texture needed to draw an image of the 1156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * given size. Return a flag indicating whether the current texture 1157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * can be re-used (glTexSubImage2D) or if a new texture needs to be 1158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * allocated (glTexImage2D). 1159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Also, compute s/t texcoords for drawing. 1160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 1161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * \return GL_TRUE if new texture is needed, GL_FALSE otherwise 1162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic GLboolean 1164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangalloc_texture(struct temp_texture *tex, 1165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLsizei width, GLsizei height, GLenum intFormat) 1166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean newTex = GL_FALSE; 1168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT(width <= tex->MaxSize); 1170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT(height <= tex->MaxSize); 1171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (width > tex->Width || 1173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang height > tex->Height || 1174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang intFormat != tex->IntFormat) { 1175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* alloc new texture (larger or different format) */ 1176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (tex->NPOT) { 1178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* use non-power of two size */ 1179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Width = MAX2(tex->MinSize, width); 1180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Height = MAX2(tex->MinSize, height); 1181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 1183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* find power of two size */ 1184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLsizei w, h; 1185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang w = h = tex->MinSize; 1186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (w < width) 1187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang w *= 2; 1188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (h < height) 1189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang h *= 2; 1190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Width = w; 1191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Height = h; 1192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->IntFormat = intFormat; 1195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang newTex = GL_TRUE; 1197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* compute texcoords */ 1200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (tex->Target == GL_TEXTURE_RECTANGLE) { 1201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Sright = (GLfloat) width; 1202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Ttop = (GLfloat) height; 1203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 1205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Sright = (GLfloat) width / tex->Width; 1206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Ttop = (GLfloat) height / tex->Height; 1207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return newTex; 1210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 1214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Setup/load texture for glCopyPixels or glBlitFramebuffer. 1215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void 1217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangsetup_copypix_texture(struct temp_texture *tex, 1218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLboolean newTex, 1219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLint srcX, GLint srcY, 1220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLsizei width, GLsizei height, GLenum intFormat, 1221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GLenum filter) 1222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{ 1223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_BindTexture(tex->Target, tex->TexObj); 1224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter); 1225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter); 1226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* copy framebuffer image to texture */ 1229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (newTex) { 1230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* create new tex image */ 1231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (tex->Width == width && tex->Height == height) { 1232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* create new tex with framebuffer data */ 1233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat, 1234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang srcX, srcY, width, height, 0); 1235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 1237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* create empty texture */ 1238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, 1239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tex->Width, tex->Height, 0, 1240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang intFormat, GL_UNSIGNED_BYTE, NULL); 1241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* load image */ 1242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_CopyTexSubImage2D(tex->Target, 0, 1243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 0, 0, srcX, srcY, width, height); 1244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 12475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* replace existing tex image */ 1248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_CopyTexSubImage2D(tex->Target, 0, 1249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 0, 0, srcX, srcY, width, height); 1250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/** 12555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * Setup/load texture for glDrawPixels. 12565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang */ 12575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void 12585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangsetup_drawpix_texture(struct gl_context *ctx, 12595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang struct temp_texture *tex, 12605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLboolean newTex, 12615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLenum texIntFormat, 12625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLsizei width, GLsizei height, 12635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLenum format, GLenum type, 12645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang const GLvoid *pixels) 12655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang{ 1266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _mesa_BindTexture(tex->Target, tex->TexObj); 12675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 12685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 12695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 12705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 12715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* copy pixel data to texture */ 12725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (newTex) { 12735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* create new tex image */ 12745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (tex->Width == width && tex->Height == height) { 12755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* create new tex and load image data */ 12765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, 1277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian tex->Width, tex->Height, 0, format, type, pixels); 12785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang } 12795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang else { 1280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct gl_buffer_object *save_unpack_obj = NULL; 12815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 12825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_reference_buffer_object(ctx, &save_unpack_obj, 12835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang ctx->Unpack.BufferObj); 12845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 12855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* create empty texture */ 12865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, 12875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang tex->Width, tex->Height, 0, format, type, NULL); 12885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (save_unpack_obj != NULL) 12895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 12905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang save_unpack_obj->Name); 12915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* load image */ 12925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexSubImage2D(tex->Target, 0, 1293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 0, 0, width, height, format, type, pixels); 1294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else { 1297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* replace existing tex image */ 1298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _mesa_TexSubImage2D(tex->Target, 0, 1299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 0, 0, width, height, format, type, pixels); 1300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 1302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 13045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang/** 1306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * One-time init for drawing depth pixels. 1307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 1308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void 13095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuanginit_blit_depth_pixels(struct gl_context *ctx) 13105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang{ 13115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang static const char *program = 13125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang "!!ARBfp1.0\n" 1313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" 1314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "END \n"; 13155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang char program2[200]; 13165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang struct blit_state *blit = &ctx->Meta->Blit; 13175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang struct temp_texture *tex = get_temp_texture(ctx); 13185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang const char *texTarget; 13195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang assert(blit->DepthFP == 0); 13215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* replace %s with "RECT" or "2D" */ 13235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang assert(strlen(program) + 4 < sizeof(program2)); 13245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (tex->Target == GL_TEXTURE_RECTANGLE) 13255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang texTarget = "RECT"; 13265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang else 13275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang texTarget = "2D"; 13285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_snprintf(program2, sizeof(program2), program, texTarget); 13295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_GenPrograms(1, &blit->DepthFP); 13315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); 13325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 13335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang strlen(program2), (const GLubyte *) program2); 13345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang} 13355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang/** 13385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * Try to do a glBlitFramebuffer using no-copy texturing. 13395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * We can do this when the src renderbuffer is actually a texture. 13405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * But if the src buffer == dst buffer we cannot do this. 13415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * 13425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * \return new buffer mask indicating the buffers left to blit using the 13435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang * normal path. 13445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang */ 13455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic GLbitfield 13465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangblitframebuffer_texture(struct gl_context *ctx, 13475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLbitfield mask, GLenum filter) 1350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1351b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (mask & GL_COLOR_BUFFER_BIT) { 1352b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const struct gl_framebuffer *drawFb = ctx->DrawBuffer; 1353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const struct gl_framebuffer *readFb = ctx->ReadBuffer; 1354b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const struct gl_renderbuffer_attachment *drawAtt = 13555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]]; 13565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang const struct gl_renderbuffer_attachment *readAtt = 13575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang &readFb->Attachment[readFb->_ColorReadBufferIndex]; 13585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (readAtt && readAtt->Texture) { 13605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang const struct gl_texture_object *texObj = readAtt->Texture; 1361b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const GLuint srcLevel = readAtt->TextureLevel; 1362b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const GLint baseLevelSave = texObj->BaseLevel; 1363b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const GLint maxLevelSave = texObj->MaxLevel; 1364b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled; 1365b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const GLenum target = texObj->Target; 1366b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian GLuint sampler, samplerSave = 1367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? 13685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; 13695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (drawAtt->Texture == readAtt->Texture) { 13715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* Can't use same texture as both the source and dest. We need 1372b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * to handle overlapping blits and besides, some hw may not 1373b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * support this. 1374b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian */ 1375b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return mask; 1376b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1377b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) { 13795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* Can't handle other texture types at this time */ 13805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang return mask; 13815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang } 13825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_GenSamplers(1, &sampler); 13845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); 13855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* 13875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang printf("Blit from texture!\n"); 13885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang printf(" srcAtt %p dstAtt %p\n", readAtt, drawAtt); 13895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture); 13905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang */ 13915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 13925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* Prepare src texture state */ 13935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_BindTexture(target, texObj->Name); 13945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filter); 1395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, filter); 13965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (target != GL_TEXTURE_RECTANGLE_ARB) { 13975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel); 13985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); 13995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang } 14005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 14015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 14025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 14035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang /* Always do our blits with no sRGB decode or encode.*/ 1404b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ctx->Extensions.EXT_texture_sRGB_decode) { 14055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang _mesa_SamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, 1406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GL_SKIP_DECODE_EXT); 1407 } 1408 if (ctx->Extensions.EXT_framebuffer_sRGB) { 1409 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); 1410 } 1411 1412 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1413 _mesa_set_enable(ctx, target, GL_TRUE); 1414 1415 /* Prepare vertex data (the VBO was previously created and bound) */ 1416 { 1417 struct vertex { 1418 GLfloat x, y, s, t; 1419 }; 1420 struct vertex verts[4]; 1421 GLfloat s0, t0, s1, t1; 1422 1423 if (target == GL_TEXTURE_2D) { 1424 const struct gl_texture_image *texImage 1425 = _mesa_select_tex_image(ctx, texObj, target, srcLevel); 1426 s0 = srcX0 / (float) texImage->Width; 1427 s1 = srcX1 / (float) texImage->Width; 1428 t0 = srcY0 / (float) texImage->Height; 1429 t1 = srcY1 / (float) texImage->Height; 1430 } 1431 else { 1432 assert(target == GL_TEXTURE_RECTANGLE_ARB); 1433 s0 = srcX0; 1434 s1 = srcX1; 1435 t0 = srcY0; 1436 t1 = srcY1; 1437 } 1438 1439 verts[0].x = (GLfloat) dstX0; 1440 verts[0].y = (GLfloat) dstY0; 1441 verts[1].x = (GLfloat) dstX1; 1442 verts[1].y = (GLfloat) dstY0; 1443 verts[2].x = (GLfloat) dstX1; 1444 verts[2].y = (GLfloat) dstY1; 1445 verts[3].x = (GLfloat) dstX0; 1446 verts[3].y = (GLfloat) dstY1; 1447 1448 verts[0].s = s0; 1449 verts[0].t = t0; 1450 verts[1].s = s1; 1451 verts[1].t = t0; 1452 verts[2].s = s1; 1453 verts[2].t = t1; 1454 verts[3].s = s0; 1455 verts[3].t = t1; 1456 1457 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 1458 } 1459 1460 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1461 1462 /* Restore texture object state, the texture binding will 1463 * be restored by _mesa_meta_end(). 1464 */ 1465 if (target != GL_TEXTURE_RECTANGLE_ARB) { 1466 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); 1467 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); 1468 } 1469 if (ctx->Extensions.EXT_framebuffer_sRGB && fbo_srgb_save) { 1470 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE); 1471 } 1472 1473 _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); 1474 _mesa_DeleteSamplers(1, &sampler); 1475 1476 /* Done with color buffer */ 1477 mask &= ~GL_COLOR_BUFFER_BIT; 1478 } 1479 } 1480 1481 return mask; 1482} 1483 1484 1485/** 1486 * Meta implementation of ctx->Driver.BlitFramebuffer() in terms 1487 * of texture mapping and polygon rendering. 1488 */ 1489void 1490_mesa_meta_BlitFramebuffer(struct gl_context *ctx, 1491 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1492 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1493 GLbitfield mask, GLenum filter) 1494{ 1495 struct blit_state *blit = &ctx->Meta->Blit; 1496 struct temp_texture *tex = get_temp_texture(ctx); 1497 const GLsizei maxTexSize = tex->MaxSize; 1498 const GLint srcX = MIN2(srcX0, srcX1); 1499 const GLint srcY = MIN2(srcY0, srcY1); 1500 const GLint srcW = abs(srcX1 - srcX0); 1501 const GLint srcH = abs(srcY1 - srcY0); 1502 const GLboolean srcFlipX = srcX1 < srcX0; 1503 const GLboolean srcFlipY = srcY1 < srcY0; 1504 struct vertex { 1505 GLfloat x, y, s, t; 1506 }; 1507 struct vertex verts[4]; 1508 GLboolean newTex; 1509 1510 /* In addition to falling back if the blit size is larger than the maximum 1511 * texture size, fallback if the source is multisampled. This fallback can 1512 * be removed once Mesa gets support ARB_texture_multisample. 1513 */ 1514 if (srcW > maxTexSize || srcH > maxTexSize 1515 || ctx->ReadBuffer->Visual.samples > 0) { 1516 /* XXX avoid this fallback */ 1517 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, 1518 dstX0, dstY0, dstX1, dstY1, mask, filter); 1519 return; 1520 } 1521 1522 if (srcFlipX) { 1523 GLint tmp = dstX0; 1524 dstX0 = dstX1; 1525 dstX1 = tmp; 1526 } 1527 1528 if (srcFlipY) { 1529 GLint tmp = dstY0; 1530 dstY0 = dstY1; 1531 dstY1 = tmp; 1532 } 1533 1534 /* only scissor effects blit so save/clear all other relevant state */ 1535 _mesa_meta_begin(ctx, ~MESA_META_SCISSOR); 1536 1537 if (blit->ArrayObj == 0) { 1538 /* one-time setup */ 1539 1540 /* create vertex array object */ 1541 _mesa_GenVertexArrays(1, &blit->ArrayObj); 1542 _mesa_BindVertexArray(blit->ArrayObj); 1543 1544 /* create vertex array buffer */ 1545 _mesa_GenBuffersARB(1, &blit->VBO); 1546 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO); 1547 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 1548 NULL, GL_DYNAMIC_DRAW_ARB); 1549 1550 /* setup vertex arrays */ 1551 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 1552 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 1553 _mesa_EnableClientState(GL_VERTEX_ARRAY); 1554 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 1555 } 1556 else { 1557 _mesa_BindVertexArray(blit->ArrayObj); 1558 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO); 1559 } 1560 1561 /* Try faster, direct texture approach first */ 1562 mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1, 1563 dstX0, dstY0, dstX1, dstY1, mask, filter); 1564 if (mask == 0x0) { 1565 _mesa_meta_end(ctx); 1566 return; 1567 } 1568 1569 /* Continue with "normal" approach which involves copying the src rect 1570 * into a temporary texture and is "blitted" by drawing a textured quad. 1571 */ 1572 1573 newTex = alloc_texture(tex, srcW, srcH, GL_RGBA); 1574 1575 /* vertex positions/texcoords (after texture allocation!) */ 1576 { 1577 verts[0].x = (GLfloat) dstX0; 1578 verts[0].y = (GLfloat) dstY0; 1579 verts[1].x = (GLfloat) dstX1; 1580 verts[1].y = (GLfloat) dstY0; 1581 verts[2].x = (GLfloat) dstX1; 1582 verts[2].y = (GLfloat) dstY1; 1583 verts[3].x = (GLfloat) dstX0; 1584 verts[3].y = (GLfloat) dstY1; 1585 1586 verts[0].s = 0.0F; 1587 verts[0].t = 0.0F; 1588 verts[1].s = tex->Sright; 1589 verts[1].t = 0.0F; 1590 verts[2].s = tex->Sright; 1591 verts[2].t = tex->Ttop; 1592 verts[3].s = 0.0F; 1593 verts[3].t = tex->Ttop; 1594 1595 /* upload new vertex data */ 1596 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 1597 } 1598 1599 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 1600 1601 if (mask & GL_COLOR_BUFFER_BIT) { 1602 setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH, 1603 GL_RGBA, filter); 1604 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1605 mask &= ~GL_COLOR_BUFFER_BIT; 1606 } 1607 1608 if (mask & GL_DEPTH_BUFFER_BIT) { 1609 GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint)); 1610 if (tmp) { 1611 if (!blit->DepthFP) 1612 init_blit_depth_pixels(ctx); 1613 1614 /* maybe change tex format here */ 1615 newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT); 1616 1617 _mesa_ReadPixels(srcX, srcY, srcW, srcH, 1618 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); 1619 1620 setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH, 1621 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); 1622 1623 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); 1624 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); 1625 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1626 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); 1627 _mesa_DepthFunc(GL_ALWAYS); 1628 _mesa_DepthMask(GL_TRUE); 1629 1630 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1631 mask &= ~GL_DEPTH_BUFFER_BIT; 1632 1633 free(tmp); 1634 } 1635 } 1636 1637 if (mask & GL_STENCIL_BUFFER_BIT) { 1638 /* XXX can't easily do stencil */ 1639 } 1640 1641 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 1642 1643 _mesa_meta_end(ctx); 1644 1645 if (mask) { 1646 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, 1647 dstX0, dstY0, dstX1, dstY1, mask, filter); 1648 } 1649} 1650 1651static void 1652meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) 1653{ 1654 if (blit->ArrayObj) { 1655 _mesa_DeleteVertexArraysAPPLE(1, &blit->ArrayObj); 1656 blit->ArrayObj = 0; 1657 _mesa_DeleteBuffersARB(1, &blit->VBO); 1658 blit->VBO = 0; 1659 } 1660 if (blit->DepthFP) { 1661 _mesa_DeletePrograms(1, &blit->DepthFP); 1662 blit->DepthFP = 0; 1663 } 1664} 1665 1666 1667/** 1668 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. 1669 */ 1670void 1671_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) 1672{ 1673 struct clear_state *clear = &ctx->Meta->Clear; 1674 struct vertex { 1675 GLfloat x, y, z, r, g, b, a; 1676 }; 1677 struct vertex verts[4]; 1678 /* save all state but scissor, pixel pack/unpack */ 1679 GLbitfield metaSave = (MESA_META_ALL - 1680 MESA_META_SCISSOR - 1681 MESA_META_PIXEL_STORE - 1682 MESA_META_CONDITIONAL_RENDER); 1683 const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 1684 1685 if (buffers & BUFFER_BITS_COLOR) { 1686 /* if clearing color buffers, don't save/restore colormask */ 1687 metaSave -= MESA_META_COLOR_MASK; 1688 } 1689 1690 _mesa_meta_begin(ctx, metaSave); 1691 1692 if (clear->ArrayObj == 0) { 1693 /* one-time setup */ 1694 1695 /* create vertex array object */ 1696 _mesa_GenVertexArrays(1, &clear->ArrayObj); 1697 _mesa_BindVertexArray(clear->ArrayObj); 1698 1699 /* create vertex array buffer */ 1700 _mesa_GenBuffersARB(1, &clear->VBO); 1701 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1702 1703 /* setup vertex arrays */ 1704 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 1705 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); 1706 _mesa_EnableClientState(GL_VERTEX_ARRAY); 1707 _mesa_EnableClientState(GL_COLOR_ARRAY); 1708 } 1709 else { 1710 _mesa_BindVertexArray(clear->ArrayObj); 1711 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1712 } 1713 1714 /* GL_COLOR_BUFFER_BIT */ 1715 if (buffers & BUFFER_BITS_COLOR) { 1716 /* leave colormask, glDrawBuffer state as-is */ 1717 1718 /* Clears never have the color clamped. */ 1719 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 1720 } 1721 else { 1722 ASSERT(metaSave & MESA_META_COLOR_MASK); 1723 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1724 } 1725 1726 /* GL_DEPTH_BUFFER_BIT */ 1727 if (buffers & BUFFER_BIT_DEPTH) { 1728 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); 1729 _mesa_DepthFunc(GL_ALWAYS); 1730 _mesa_DepthMask(GL_TRUE); 1731 } 1732 else { 1733 assert(!ctx->Depth.Test); 1734 } 1735 1736 /* GL_STENCIL_BUFFER_BIT */ 1737 if (buffers & BUFFER_BIT_STENCIL) { 1738 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); 1739 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, 1740 GL_REPLACE, GL_REPLACE, GL_REPLACE); 1741 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 1742 ctx->Stencil.Clear & stencilMax, 1743 ctx->Stencil.WriteMask[0]); 1744 } 1745 else { 1746 assert(!ctx->Stencil.Enabled); 1747 } 1748 1749 /* vertex positions/colors */ 1750 { 1751 const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin; 1752 const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin; 1753 const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax; 1754 const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax; 1755 const GLfloat z = invert_z(ctx->Depth.Clear); 1756 GLuint i; 1757 1758 verts[0].x = x0; 1759 verts[0].y = y0; 1760 verts[0].z = z; 1761 verts[1].x = x1; 1762 verts[1].y = y0; 1763 verts[1].z = z; 1764 verts[2].x = x1; 1765 verts[2].y = y1; 1766 verts[2].z = z; 1767 verts[3].x = x0; 1768 verts[3].y = y1; 1769 verts[3].z = z; 1770 1771 /* vertex colors */ 1772 for (i = 0; i < 4; i++) { 1773 verts[i].r = ctx->Color.ClearColor.f[0]; 1774 verts[i].g = ctx->Color.ClearColor.f[1]; 1775 verts[i].b = ctx->Color.ClearColor.f[2]; 1776 verts[i].a = ctx->Color.ClearColor.f[3]; 1777 } 1778 1779 /* upload new vertex data */ 1780 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, 1781 GL_DYNAMIC_DRAW_ARB); 1782 } 1783 1784 /* draw quad */ 1785 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1786 1787 _mesa_meta_end(ctx); 1788} 1789 1790static void 1791meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) 1792{ 1793 const char *vs_source = 1794 "attribute vec4 position;\n" 1795 "void main()\n" 1796 "{\n" 1797 " gl_Position = position;\n" 1798 "}\n"; 1799 const char *fs_source = 1800 "uniform vec4 color;\n" 1801 "void main()\n" 1802 "{\n" 1803 " gl_FragColor = color;\n" 1804 "}\n"; 1805 const char *vs_int_source = 1806 "#version 130\n" 1807 "attribute vec4 position;\n" 1808 "void main()\n" 1809 "{\n" 1810 " gl_Position = position;\n" 1811 "}\n"; 1812 const char *fs_int_source = 1813 "#version 130\n" 1814 "uniform ivec4 color;\n" 1815 "out ivec4 out_color;\n" 1816 "\n" 1817 "void main()\n" 1818 "{\n" 1819 " out_color = color;\n" 1820 "}\n"; 1821 GLuint vs, fs; 1822 1823 if (clear->ArrayObj != 0) 1824 return; 1825 1826 /* create vertex array object */ 1827 _mesa_GenVertexArrays(1, &clear->ArrayObj); 1828 _mesa_BindVertexArray(clear->ArrayObj); 1829 1830 /* create vertex array buffer */ 1831 _mesa_GenBuffersARB(1, &clear->VBO); 1832 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1833 1834 /* setup vertex arrays */ 1835 _mesa_VertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); 1836 _mesa_EnableVertexAttribArrayARB(0); 1837 1838 vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER); 1839 _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL); 1840 _mesa_CompileShaderARB(vs); 1841 1842 fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER); 1843 _mesa_ShaderSourceARB(fs, 1, &fs_source, NULL); 1844 _mesa_CompileShaderARB(fs); 1845 1846 clear->ShaderProg = _mesa_CreateProgramObjectARB(); 1847 _mesa_AttachShader(clear->ShaderProg, fs); 1848 _mesa_DeleteObjectARB(fs); 1849 _mesa_AttachShader(clear->ShaderProg, vs); 1850 _mesa_DeleteObjectARB(vs); 1851 _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position"); 1852 _mesa_LinkProgramARB(clear->ShaderProg); 1853 1854 clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg, 1855 "color"); 1856 1857 if (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) { 1858 vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source); 1859 fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source); 1860 1861 clear->IntegerShaderProg = _mesa_CreateProgramObjectARB(); 1862 _mesa_AttachShader(clear->IntegerShaderProg, fs); 1863 _mesa_DeleteObjectARB(fs); 1864 _mesa_AttachShader(clear->IntegerShaderProg, vs); 1865 _mesa_DeleteObjectARB(vs); 1866 _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position"); 1867 1868 /* Note that user-defined out attributes get automatically assigned 1869 * locations starting from 0, so we don't need to explicitly 1870 * BindFragDataLocation to 0. 1871 */ 1872 1873 link_program_with_debug(ctx, clear->IntegerShaderProg); 1874 1875 clear->IntegerColorLocation = 1876 _mesa_GetUniformLocationARB(clear->IntegerShaderProg, "color"); 1877 } 1878} 1879 1880static void 1881meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear) 1882{ 1883 if (clear->ArrayObj == 0) 1884 return; 1885 _mesa_DeleteVertexArraysAPPLE(1, &clear->ArrayObj); 1886 clear->ArrayObj = 0; 1887 _mesa_DeleteBuffersARB(1, &clear->VBO); 1888 clear->VBO = 0; 1889 _mesa_DeleteObjectARB(clear->ShaderProg); 1890 clear->ShaderProg = 0; 1891 1892 if (clear->IntegerShaderProg) { 1893 _mesa_DeleteObjectARB(clear->IntegerShaderProg); 1894 clear->IntegerShaderProg = 0; 1895 } 1896} 1897 1898/** 1899 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. 1900 */ 1901void 1902_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) 1903{ 1904 struct clear_state *clear = &ctx->Meta->Clear; 1905 GLbitfield metaSave; 1906 const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 1907 struct gl_framebuffer *fb = ctx->DrawBuffer; 1908 const float x0 = ((float)fb->_Xmin / fb->Width) * 2.0f - 1.0f; 1909 const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f; 1910 const float x1 = ((float)fb->_Xmax / fb->Width) * 2.0f - 1.0f; 1911 const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f; 1912 const float z = -invert_z(ctx->Depth.Clear); 1913 struct vertex { 1914 GLfloat x, y, z; 1915 } verts[4]; 1916 1917 metaSave = (MESA_META_ALPHA_TEST | 1918 MESA_META_BLEND | 1919 MESA_META_DEPTH_TEST | 1920 MESA_META_RASTERIZATION | 1921 MESA_META_SHADER | 1922 MESA_META_STENCIL_TEST | 1923 MESA_META_VERTEX | 1924 MESA_META_VIEWPORT | 1925 MESA_META_CLIP | 1926 MESA_META_CLAMP_FRAGMENT_COLOR | 1927 MESA_META_MULTISAMPLE); 1928 1929 if (!(buffers & BUFFER_BITS_COLOR)) { 1930 /* We'll use colormask to disable color writes. Otherwise, 1931 * respect color mask 1932 */ 1933 metaSave |= MESA_META_COLOR_MASK; 1934 } 1935 1936 _mesa_meta_begin(ctx, metaSave); 1937 1938 meta_glsl_clear_init(ctx, clear); 1939 1940 if (fb->_IntegerColor) { 1941 _mesa_UseProgramObjectARB(clear->IntegerShaderProg); 1942 _mesa_Uniform4ivARB(clear->IntegerColorLocation, 1, 1943 ctx->Color.ClearColor.i); 1944 } else { 1945 _mesa_UseProgramObjectARB(clear->ShaderProg); 1946 _mesa_Uniform4fvARB(clear->ColorLocation, 1, 1947 ctx->Color.ClearColor.f); 1948 } 1949 1950 _mesa_BindVertexArray(clear->ArrayObj); 1951 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1952 1953 /* GL_COLOR_BUFFER_BIT */ 1954 if (buffers & BUFFER_BITS_COLOR) { 1955 /* leave colormask, glDrawBuffer state as-is */ 1956 1957 /* Clears never have the color clamped. */ 1958 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 1959 } 1960 else { 1961 ASSERT(metaSave & MESA_META_COLOR_MASK); 1962 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1963 } 1964 1965 /* GL_DEPTH_BUFFER_BIT */ 1966 if (buffers & BUFFER_BIT_DEPTH) { 1967 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); 1968 _mesa_DepthFunc(GL_ALWAYS); 1969 _mesa_DepthMask(GL_TRUE); 1970 } 1971 else { 1972 assert(!ctx->Depth.Test); 1973 } 1974 1975 /* GL_STENCIL_BUFFER_BIT */ 1976 if (buffers & BUFFER_BIT_STENCIL) { 1977 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); 1978 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, 1979 GL_REPLACE, GL_REPLACE, GL_REPLACE); 1980 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 1981 ctx->Stencil.Clear & stencilMax, 1982 ctx->Stencil.WriteMask[0]); 1983 } 1984 else { 1985 assert(!ctx->Stencil.Enabled); 1986 } 1987 1988 /* vertex positions */ 1989 verts[0].x = x0; 1990 verts[0].y = y0; 1991 verts[0].z = z; 1992 verts[1].x = x1; 1993 verts[1].y = y0; 1994 verts[1].z = z; 1995 verts[2].x = x1; 1996 verts[2].y = y1; 1997 verts[2].z = z; 1998 verts[3].x = x0; 1999 verts[3].y = y1; 2000 verts[3].z = z; 2001 2002 /* upload new vertex data */ 2003 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, 2004 GL_DYNAMIC_DRAW_ARB); 2005 2006 /* draw quad */ 2007 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2008 2009 _mesa_meta_end(ctx); 2010} 2011 2012/** 2013 * Meta implementation of ctx->Driver.CopyPixels() in terms 2014 * of texture mapping and polygon rendering and GLSL shaders. 2015 */ 2016void 2017_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, 2018 GLsizei width, GLsizei height, 2019 GLint dstX, GLint dstY, GLenum type) 2020{ 2021 struct copypix_state *copypix = &ctx->Meta->CopyPix; 2022 struct temp_texture *tex = get_temp_texture(ctx); 2023 struct vertex { 2024 GLfloat x, y, z, s, t; 2025 }; 2026 struct vertex verts[4]; 2027 GLboolean newTex; 2028 GLenum intFormat = GL_RGBA; 2029 2030 if (type != GL_COLOR || 2031 ctx->_ImageTransferState || 2032 ctx->Fog.Enabled || 2033 width > tex->MaxSize || 2034 height > tex->MaxSize) { 2035 /* XXX avoid this fallback */ 2036 _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type); 2037 return; 2038 } 2039 2040 /* Most GL state applies to glCopyPixels, but a there's a few things 2041 * we need to override: 2042 */ 2043 _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | 2044 MESA_META_SHADER | 2045 MESA_META_TEXTURE | 2046 MESA_META_TRANSFORM | 2047 MESA_META_CLIP | 2048 MESA_META_VERTEX | 2049 MESA_META_VIEWPORT)); 2050 2051 if (copypix->ArrayObj == 0) { 2052 /* one-time setup */ 2053 2054 /* create vertex array object */ 2055 _mesa_GenVertexArrays(1, ©pix->ArrayObj); 2056 _mesa_BindVertexArray(copypix->ArrayObj); 2057 2058 /* create vertex array buffer */ 2059 _mesa_GenBuffersARB(1, ©pix->VBO); 2060 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO); 2061 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2062 NULL, GL_DYNAMIC_DRAW_ARB); 2063 2064 /* setup vertex arrays */ 2065 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2066 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 2067 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2068 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2069 } 2070 else { 2071 _mesa_BindVertexArray(copypix->ArrayObj); 2072 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO); 2073 } 2074 2075 newTex = alloc_texture(tex, width, height, intFormat); 2076 2077 /* vertex positions, texcoords (after texture allocation!) */ 2078 { 2079 const GLfloat dstX0 = (GLfloat) dstX; 2080 const GLfloat dstY0 = (GLfloat) dstY; 2081 const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX; 2082 const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY; 2083 const GLfloat z = invert_z(ctx->Current.RasterPos[2]); 2084 2085 verts[0].x = dstX0; 2086 verts[0].y = dstY0; 2087 verts[0].z = z; 2088 verts[0].s = 0.0F; 2089 verts[0].t = 0.0F; 2090 verts[1].x = dstX1; 2091 verts[1].y = dstY0; 2092 verts[1].z = z; 2093 verts[1].s = tex->Sright; 2094 verts[1].t = 0.0F; 2095 verts[2].x = dstX1; 2096 verts[2].y = dstY1; 2097 verts[2].z = z; 2098 verts[2].s = tex->Sright; 2099 verts[2].t = tex->Ttop; 2100 verts[3].x = dstX0; 2101 verts[3].y = dstY1; 2102 verts[3].z = z; 2103 verts[3].s = 0.0F; 2104 verts[3].t = tex->Ttop; 2105 2106 /* upload new vertex data */ 2107 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 2108 } 2109 2110 /* Alloc/setup texture */ 2111 setup_copypix_texture(tex, newTex, srcX, srcY, width, height, 2112 GL_RGBA, GL_NEAREST); 2113 2114 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 2115 2116 /* draw textured quad */ 2117 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2118 2119 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 2120 2121 _mesa_meta_end(ctx); 2122} 2123 2124 2125 2126/** 2127 * When the glDrawPixels() image size is greater than the max rectangle 2128 * texture size we use this function to break the glDrawPixels() image 2129 * into tiles which fit into the max texture size. 2130 */ 2131static void 2132tiled_draw_pixels(struct gl_context *ctx, 2133 GLint tileSize, 2134 GLint x, GLint y, GLsizei width, GLsizei height, 2135 GLenum format, GLenum type, 2136 const struct gl_pixelstore_attrib *unpack, 2137 const GLvoid *pixels) 2138{ 2139 struct gl_pixelstore_attrib tileUnpack = *unpack; 2140 GLint i, j; 2141 2142 if (tileUnpack.RowLength == 0) 2143 tileUnpack.RowLength = width; 2144 2145 for (i = 0; i < width; i += tileSize) { 2146 const GLint tileWidth = MIN2(tileSize, width - i); 2147 const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX); 2148 2149 tileUnpack.SkipPixels = unpack->SkipPixels + i; 2150 2151 for (j = 0; j < height; j += tileSize) { 2152 const GLint tileHeight = MIN2(tileSize, height - j); 2153 const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY); 2154 2155 tileUnpack.SkipRows = unpack->SkipRows + j; 2156 2157 _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight, 2158 format, type, &tileUnpack, pixels); 2159 } 2160 } 2161} 2162 2163 2164/** 2165 * One-time init for drawing stencil pixels. 2166 */ 2167static void 2168init_draw_stencil_pixels(struct gl_context *ctx) 2169{ 2170 /* This program is run eight times, once for each stencil bit. 2171 * The stencil values to draw are found in an 8-bit alpha texture. 2172 * We read the texture/stencil value and test if bit 'b' is set. 2173 * If the bit is not set, use KIL to kill the fragment. 2174 * Finally, we use the stencil test to update the stencil buffer. 2175 * 2176 * The basic algorithm for checking if a bit is set is: 2177 * if (is_odd(value / (1 << bit))) 2178 * result is one (or non-zero). 2179 * else 2180 * result is zero. 2181 * The program parameter contains three values: 2182 * parm.x = 255 / (1 << bit) 2183 * parm.y = 0.5 2184 * parm.z = 0.0 2185 */ 2186 static const char *program = 2187 "!!ARBfp1.0\n" 2188 "PARAM parm = program.local[0]; \n" 2189 "TEMP t; \n" 2190 "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */ 2191 "# t = t * 255 / bit \n" 2192 "MUL t.x, t.a, parm.x; \n" 2193 "# t = (int) t \n" 2194 "FRC t.y, t.x; \n" 2195 "SUB t.x, t.x, t.y; \n" 2196 "# t = t * 0.5 \n" 2197 "MUL t.x, t.x, parm.y; \n" 2198 "# t = fract(t.x) \n" 2199 "FRC t.x, t.x; # if t.x != 0, then the bit is set \n" 2200 "# t.x = (t.x == 0 ? 1 : 0) \n" 2201 "SGE t.x, -t.x, parm.z; \n" 2202 "KIL -t.x; \n" 2203 "# for debug only \n" 2204 "#MOV result.color, t.x; \n" 2205 "END \n"; 2206 char program2[1000]; 2207 struct drawpix_state *drawpix = &ctx->Meta->DrawPix; 2208 struct temp_texture *tex = get_temp_texture(ctx); 2209 const char *texTarget; 2210 2211 assert(drawpix->StencilFP == 0); 2212 2213 /* replace %s with "RECT" or "2D" */ 2214 assert(strlen(program) + 4 < sizeof(program2)); 2215 if (tex->Target == GL_TEXTURE_RECTANGLE) 2216 texTarget = "RECT"; 2217 else 2218 texTarget = "2D"; 2219 _mesa_snprintf(program2, sizeof(program2), program, texTarget); 2220 2221 _mesa_GenPrograms(1, &drawpix->StencilFP); 2222 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); 2223 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 2224 strlen(program2), (const GLubyte *) program2); 2225} 2226 2227 2228/** 2229 * One-time init for drawing depth pixels. 2230 */ 2231static void 2232init_draw_depth_pixels(struct gl_context *ctx) 2233{ 2234 static const char *program = 2235 "!!ARBfp1.0\n" 2236 "PARAM color = program.local[0]; \n" 2237 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" 2238 "MOV result.color, color; \n" 2239 "END \n"; 2240 char program2[200]; 2241 struct drawpix_state *drawpix = &ctx->Meta->DrawPix; 2242 struct temp_texture *tex = get_temp_texture(ctx); 2243 const char *texTarget; 2244 2245 assert(drawpix->DepthFP == 0); 2246 2247 /* replace %s with "RECT" or "2D" */ 2248 assert(strlen(program) + 4 < sizeof(program2)); 2249 if (tex->Target == GL_TEXTURE_RECTANGLE) 2250 texTarget = "RECT"; 2251 else 2252 texTarget = "2D"; 2253 _mesa_snprintf(program2, sizeof(program2), program, texTarget); 2254 2255 _mesa_GenPrograms(1, &drawpix->DepthFP); 2256 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); 2257 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 2258 strlen(program2), (const GLubyte *) program2); 2259} 2260 2261 2262/** 2263 * Meta implementation of ctx->Driver.DrawPixels() in terms 2264 * of texture mapping and polygon rendering. 2265 */ 2266void 2267_mesa_meta_DrawPixels(struct gl_context *ctx, 2268 GLint x, GLint y, GLsizei width, GLsizei height, 2269 GLenum format, GLenum type, 2270 const struct gl_pixelstore_attrib *unpack, 2271 const GLvoid *pixels) 2272{ 2273 struct drawpix_state *drawpix = &ctx->Meta->DrawPix; 2274 struct temp_texture *tex = get_temp_texture(ctx); 2275 const struct gl_pixelstore_attrib unpackSave = ctx->Unpack; 2276 const GLuint origStencilMask = ctx->Stencil.WriteMask[0]; 2277 struct vertex { 2278 GLfloat x, y, z, s, t; 2279 }; 2280 struct vertex verts[4]; 2281 GLenum texIntFormat; 2282 GLboolean fallback, newTex; 2283 GLbitfield metaExtraSave = 0x0; 2284 GLuint vbo; 2285 2286 /* 2287 * Determine if we can do the glDrawPixels with texture mapping. 2288 */ 2289 fallback = GL_FALSE; 2290 if (ctx->Fog.Enabled) { 2291 fallback = GL_TRUE; 2292 } 2293 2294 if (_mesa_is_color_format(format)) { 2295 /* use more compact format when possible */ 2296 /* XXX disable special case for GL_LUMINANCE for now to work around 2297 * apparent i965 driver bug (see bug #23670). 2298 */ 2299 if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA) 2300 texIntFormat = format; 2301 else 2302 texIntFormat = GL_RGBA; 2303 2304 /* If we're not supposed to clamp the resulting color, then just 2305 * promote our texture to fully float. We could do better by 2306 * just going for the matching set of channels, in floating 2307 * point. 2308 */ 2309 if (ctx->Color.ClampFragmentColor != GL_TRUE && 2310 ctx->Extensions.ARB_texture_float) 2311 texIntFormat = GL_RGBA32F; 2312 } 2313 else if (_mesa_is_stencil_format(format)) { 2314 if (ctx->Extensions.ARB_fragment_program && 2315 ctx->Pixel.IndexShift == 0 && 2316 ctx->Pixel.IndexOffset == 0 && 2317 type == GL_UNSIGNED_BYTE) { 2318 /* We'll store stencil as alpha. This only works for GLubyte 2319 * image data because of how incoming values are mapped to alpha 2320 * in [0,1]. 2321 */ 2322 texIntFormat = GL_ALPHA; 2323 metaExtraSave = (MESA_META_COLOR_MASK | 2324 MESA_META_DEPTH_TEST | 2325 MESA_META_PIXEL_TRANSFER | 2326 MESA_META_SHADER | 2327 MESA_META_STENCIL_TEST); 2328 } 2329 else { 2330 fallback = GL_TRUE; 2331 } 2332 } 2333 else if (_mesa_is_depth_format(format)) { 2334 if (ctx->Extensions.ARB_depth_texture && 2335 ctx->Extensions.ARB_fragment_program) { 2336 texIntFormat = GL_DEPTH_COMPONENT; 2337 metaExtraSave = (MESA_META_SHADER); 2338 } 2339 else { 2340 fallback = GL_TRUE; 2341 } 2342 } 2343 else { 2344 fallback = GL_TRUE; 2345 } 2346 2347 if (fallback) { 2348 _swrast_DrawPixels(ctx, x, y, width, height, 2349 format, type, unpack, pixels); 2350 return; 2351 } 2352 2353 /* 2354 * Check image size against max texture size, draw as tiles if needed. 2355 */ 2356 if (width > tex->MaxSize || height > tex->MaxSize) { 2357 tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height, 2358 format, type, unpack, pixels); 2359 return; 2360 } 2361 2362 /* Most GL state applies to glDrawPixels (like blending, stencil, etc), 2363 * but a there's a few things we need to override: 2364 */ 2365 _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | 2366 MESA_META_SHADER | 2367 MESA_META_TEXTURE | 2368 MESA_META_TRANSFORM | 2369 MESA_META_CLIP | 2370 MESA_META_VERTEX | 2371 MESA_META_VIEWPORT | 2372 metaExtraSave)); 2373 2374 newTex = alloc_texture(tex, width, height, texIntFormat); 2375 2376 /* vertex positions, texcoords (after texture allocation!) */ 2377 { 2378 const GLfloat x0 = (GLfloat) x; 2379 const GLfloat y0 = (GLfloat) y; 2380 const GLfloat x1 = x + width * ctx->Pixel.ZoomX; 2381 const GLfloat y1 = y + height * ctx->Pixel.ZoomY; 2382 const GLfloat z = invert_z(ctx->Current.RasterPos[2]); 2383 2384 verts[0].x = x0; 2385 verts[0].y = y0; 2386 verts[0].z = z; 2387 verts[0].s = 0.0F; 2388 verts[0].t = 0.0F; 2389 verts[1].x = x1; 2390 verts[1].y = y0; 2391 verts[1].z = z; 2392 verts[1].s = tex->Sright; 2393 verts[1].t = 0.0F; 2394 verts[2].x = x1; 2395 verts[2].y = y1; 2396 verts[2].z = z; 2397 verts[2].s = tex->Sright; 2398 verts[2].t = tex->Ttop; 2399 verts[3].x = x0; 2400 verts[3].y = y1; 2401 verts[3].z = z; 2402 verts[3].s = 0.0F; 2403 verts[3].t = tex->Ttop; 2404 } 2405 2406 if (drawpix->ArrayObj == 0) { 2407 /* one-time setup: create vertex array object */ 2408 _mesa_GenVertexArrays(1, &drawpix->ArrayObj); 2409 } 2410 _mesa_BindVertexArray(drawpix->ArrayObj); 2411 2412 /* create vertex array buffer */ 2413 _mesa_GenBuffersARB(1, &vbo); 2414 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); 2415 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2416 verts, GL_DYNAMIC_DRAW_ARB); 2417 2418 /* setup vertex arrays */ 2419 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2420 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 2421 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2422 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2423 2424 /* set given unpack params */ 2425 ctx->Unpack = *unpack; 2426 2427 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 2428 2429 if (_mesa_is_stencil_format(format)) { 2430 /* Drawing stencil */ 2431 GLint bit; 2432 2433 if (!drawpix->StencilFP) 2434 init_draw_stencil_pixels(ctx); 2435 2436 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2437 GL_ALPHA, type, pixels); 2438 2439 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 2440 2441 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); 2442 2443 /* set all stencil bits to 0 */ 2444 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 2445 _mesa_StencilFunc(GL_ALWAYS, 0, 255); 2446 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2447 2448 /* set stencil bits to 1 where needed */ 2449 _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 2450 2451 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); 2452 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); 2453 2454 for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) { 2455 const GLuint mask = 1 << bit; 2456 if (mask & origStencilMask) { 2457 _mesa_StencilFunc(GL_ALWAYS, mask, mask); 2458 _mesa_StencilMask(mask); 2459 2460 _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 2461 255.0 / mask, 0.5, 0.0, 0.0); 2462 2463 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2464 } 2465 } 2466 } 2467 else if (_mesa_is_depth_format(format)) { 2468 /* Drawing depth */ 2469 if (!drawpix->DepthFP) 2470 init_draw_depth_pixels(ctx); 2471 2472 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); 2473 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); 2474 2475 /* polygon color = current raster color */ 2476 _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, 2477 ctx->Current.RasterColor); 2478 2479 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2480 format, type, pixels); 2481 2482 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2483 } 2484 else { 2485 /* Drawing RGBA */ 2486 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2487 format, type, pixels); 2488 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2489 } 2490 2491 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 2492 2493 _mesa_DeleteBuffersARB(1, &vbo); 2494 2495 /* restore unpack params */ 2496 ctx->Unpack = unpackSave; 2497 2498 _mesa_meta_end(ctx); 2499} 2500 2501static GLboolean 2502alpha_test_raster_color(struct gl_context *ctx) 2503{ 2504 GLfloat alpha = ctx->Current.RasterColor[ACOMP]; 2505 GLfloat ref = ctx->Color.AlphaRef; 2506 2507 switch (ctx->Color.AlphaFunc) { 2508 case GL_NEVER: 2509 return GL_FALSE; 2510 case GL_LESS: 2511 return alpha < ref; 2512 case GL_EQUAL: 2513 return alpha == ref; 2514 case GL_LEQUAL: 2515 return alpha <= ref; 2516 case GL_GREATER: 2517 return alpha > ref; 2518 case GL_NOTEQUAL: 2519 return alpha != ref; 2520 case GL_GEQUAL: 2521 return alpha >= ref; 2522 case GL_ALWAYS: 2523 return GL_TRUE; 2524 default: 2525 assert(0); 2526 return GL_FALSE; 2527 } 2528} 2529 2530/** 2531 * Do glBitmap with a alpha texture quad. Use the alpha test to cull 2532 * the 'off' bits. A bitmap cache as in the gallium/mesa state 2533 * tracker would improve performance a lot. 2534 */ 2535void 2536_mesa_meta_Bitmap(struct gl_context *ctx, 2537 GLint x, GLint y, GLsizei width, GLsizei height, 2538 const struct gl_pixelstore_attrib *unpack, 2539 const GLubyte *bitmap1) 2540{ 2541 struct bitmap_state *bitmap = &ctx->Meta->Bitmap; 2542 struct temp_texture *tex = get_bitmap_temp_texture(ctx); 2543 const GLenum texIntFormat = GL_ALPHA; 2544 const struct gl_pixelstore_attrib unpackSave = *unpack; 2545 GLubyte fg, bg; 2546 struct vertex { 2547 GLfloat x, y, z, s, t, r, g, b, a; 2548 }; 2549 struct vertex verts[4]; 2550 GLboolean newTex; 2551 GLubyte *bitmap8; 2552 2553 /* 2554 * Check if swrast fallback is needed. 2555 */ 2556 if (ctx->_ImageTransferState || 2557 ctx->FragmentProgram._Enabled || 2558 ctx->Fog.Enabled || 2559 ctx->Texture._EnabledUnits || 2560 width > tex->MaxSize || 2561 height > tex->MaxSize) { 2562 _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1); 2563 return; 2564 } 2565 2566 if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx)) 2567 return; 2568 2569 /* Most GL state applies to glBitmap (like blending, stencil, etc), 2570 * but a there's a few things we need to override: 2571 */ 2572 _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST | 2573 MESA_META_PIXEL_STORE | 2574 MESA_META_RASTERIZATION | 2575 MESA_META_SHADER | 2576 MESA_META_TEXTURE | 2577 MESA_META_TRANSFORM | 2578 MESA_META_CLIP | 2579 MESA_META_VERTEX | 2580 MESA_META_VIEWPORT)); 2581 2582 if (bitmap->ArrayObj == 0) { 2583 /* one-time setup */ 2584 2585 /* create vertex array object */ 2586 _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj); 2587 _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj); 2588 2589 /* create vertex array buffer */ 2590 _mesa_GenBuffersARB(1, &bitmap->VBO); 2591 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO); 2592 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2593 NULL, GL_DYNAMIC_DRAW_ARB); 2594 2595 /* setup vertex arrays */ 2596 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2597 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 2598 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); 2599 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2600 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2601 _mesa_EnableClientState(GL_COLOR_ARRAY); 2602 } 2603 else { 2604 _mesa_BindVertexArray(bitmap->ArrayObj); 2605 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO); 2606 } 2607 2608 newTex = alloc_texture(tex, width, height, texIntFormat); 2609 2610 /* vertex positions, texcoords, colors (after texture allocation!) */ 2611 { 2612 const GLfloat x0 = (GLfloat) x; 2613 const GLfloat y0 = (GLfloat) y; 2614 const GLfloat x1 = (GLfloat) (x + width); 2615 const GLfloat y1 = (GLfloat) (y + height); 2616 const GLfloat z = invert_z(ctx->Current.RasterPos[2]); 2617 GLuint i; 2618 2619 verts[0].x = x0; 2620 verts[0].y = y0; 2621 verts[0].z = z; 2622 verts[0].s = 0.0F; 2623 verts[0].t = 0.0F; 2624 verts[1].x = x1; 2625 verts[1].y = y0; 2626 verts[1].z = z; 2627 verts[1].s = tex->Sright; 2628 verts[1].t = 0.0F; 2629 verts[2].x = x1; 2630 verts[2].y = y1; 2631 verts[2].z = z; 2632 verts[2].s = tex->Sright; 2633 verts[2].t = tex->Ttop; 2634 verts[3].x = x0; 2635 verts[3].y = y1; 2636 verts[3].z = z; 2637 verts[3].s = 0.0F; 2638 verts[3].t = tex->Ttop; 2639 2640 for (i = 0; i < 4; i++) { 2641 verts[i].r = ctx->Current.RasterColor[0]; 2642 verts[i].g = ctx->Current.RasterColor[1]; 2643 verts[i].b = ctx->Current.RasterColor[2]; 2644 verts[i].a = ctx->Current.RasterColor[3]; 2645 } 2646 2647 /* upload new vertex data */ 2648 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 2649 } 2650 2651 /* choose different foreground/background alpha values */ 2652 CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]); 2653 bg = (fg > 127 ? 0 : 255); 2654 2655 bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1); 2656 if (!bitmap1) { 2657 _mesa_meta_end(ctx); 2658 return; 2659 } 2660 2661 bitmap8 = (GLubyte *) malloc(width * height); 2662 if (bitmap8) { 2663 memset(bitmap8, bg, width * height); 2664 _mesa_expand_bitmap(width, height, &unpackSave, bitmap1, 2665 bitmap8, width, fg); 2666 2667 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 2668 2669 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE); 2670 _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg)); 2671 2672 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2673 GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8); 2674 2675 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2676 2677 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 2678 2679 free(bitmap8); 2680 } 2681 2682 _mesa_unmap_pbo_source(ctx, &unpackSave); 2683 2684 _mesa_meta_end(ctx); 2685} 2686 2687 2688/** 2689 * Check if the call to _mesa_meta_GenerateMipmap() will require a 2690 * software fallback. The fallback path will require that the texture 2691 * images are mapped. 2692 * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise 2693 */ 2694GLboolean 2695_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, 2696 struct gl_texture_object *texObj) 2697{ 2698 const GLuint fboSave = ctx->DrawBuffer->Name; 2699 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; 2700 struct gl_texture_image *baseImage; 2701 GLuint srcLevel; 2702 GLenum status; 2703 2704 /* check for fallbacks */ 2705 if (!ctx->Extensions.EXT_framebuffer_object || 2706 target == GL_TEXTURE_3D || 2707 target == GL_TEXTURE_1D_ARRAY || 2708 target == GL_TEXTURE_2D_ARRAY) { 2709 return GL_TRUE; 2710 } 2711 2712 srcLevel = texObj->BaseLevel; 2713 baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); 2714 if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) { 2715 return GL_TRUE; 2716 } 2717 2718 if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB && 2719 !ctx->Extensions.EXT_texture_sRGB_decode) { 2720 /* The texture format is sRGB but we can't turn off sRGB->linear 2721 * texture sample conversion. So we won't be able to generate the 2722 * right colors when rendering. Need to use a fallback. 2723 */ 2724 return GL_TRUE; 2725 } 2726 2727 /* 2728 * Test that we can actually render in the texture's format. 2729 */ 2730 if (!mipmap->FBO) 2731 _mesa_GenFramebuffersEXT(1, &mipmap->FBO); 2732 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO); 2733 2734 if (target == GL_TEXTURE_1D) { 2735 _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, 2736 GL_COLOR_ATTACHMENT0_EXT, 2737 target, texObj->Name, srcLevel); 2738 } 2739#if 0 2740 /* other work is needed to enable 3D mipmap generation */ 2741 else if (target == GL_TEXTURE_3D) { 2742 GLint zoffset = 0; 2743 _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, 2744 GL_COLOR_ATTACHMENT0_EXT, 2745 target, texObj->Name, srcLevel, zoffset); 2746 } 2747#endif 2748 else { 2749 /* 2D / cube */ 2750 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 2751 GL_COLOR_ATTACHMENT0_EXT, 2752 target, texObj->Name, srcLevel); 2753 } 2754 2755 status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 2756 2757 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave); 2758 2759 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2760 return GL_TRUE; 2761 } 2762 2763 return GL_FALSE; 2764} 2765 2766 2767/** 2768 * Compute the texture coordinates for the four vertices of a quad for 2769 * drawing a 2D texture image or slice of a cube/3D texture. 2770 * \param faceTarget GL_TEXTURE_1D/2D/3D or cube face name 2771 * \param slice slice of a 1D/2D array texture or 3D texture 2772 * \param width width of the texture image 2773 * \param height height of the texture image 2774 * \param coords0/1/2/3 returns the computed texcoords 2775 */ 2776static void 2777setup_texture_coords(GLenum faceTarget, 2778 GLint slice, 2779 GLint width, 2780 GLint height, 2781 GLfloat coords0[3], 2782 GLfloat coords1[3], 2783 GLfloat coords2[3], 2784 GLfloat coords3[3]) 2785{ 2786 static const GLfloat st[4][2] = { 2787 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} 2788 }; 2789 GLuint i; 2790 GLfloat r; 2791 2792 switch (faceTarget) { 2793 case GL_TEXTURE_1D: 2794 case GL_TEXTURE_2D: 2795 case GL_TEXTURE_3D: 2796 case GL_TEXTURE_2D_ARRAY: 2797 if (faceTarget == GL_TEXTURE_3D) 2798 r = 1.0F / slice; 2799 else if (faceTarget == GL_TEXTURE_2D_ARRAY) 2800 r = slice; 2801 else 2802 r = 0.0F; 2803 coords0[0] = 0.0F; /* s */ 2804 coords0[1] = 0.0F; /* t */ 2805 coords0[2] = r; /* r */ 2806 coords1[0] = 1.0F; 2807 coords1[1] = 0.0F; 2808 coords1[2] = r; 2809 coords2[0] = 1.0F; 2810 coords2[1] = 1.0F; 2811 coords2[2] = r; 2812 coords3[0] = 0.0F; 2813 coords3[1] = 1.0F; 2814 coords3[2] = r; 2815 break; 2816 case GL_TEXTURE_RECTANGLE_ARB: 2817 coords0[0] = 0.0F; /* s */ 2818 coords0[1] = 0.0F; /* t */ 2819 coords0[2] = 0.0F; /* r */ 2820 coords1[0] = width; 2821 coords1[1] = 0.0F; 2822 coords1[2] = 0.0F; 2823 coords2[0] = width; 2824 coords2[1] = height; 2825 coords2[2] = 0.0F; 2826 coords3[0] = 0.0F; 2827 coords3[1] = height; 2828 coords3[2] = 0.0F; 2829 break; 2830 case GL_TEXTURE_1D_ARRAY: 2831 coords0[0] = 0.0F; /* s */ 2832 coords0[1] = slice; /* t */ 2833 coords0[2] = 0.0F; /* r */ 2834 coords1[0] = 1.0f; 2835 coords1[1] = slice; 2836 coords1[2] = 0.0F; 2837 coords2[0] = 1.0F; 2838 coords2[1] = slice; 2839 coords2[2] = 0.0F; 2840 coords3[0] = 0.0F; 2841 coords3[1] = slice; 2842 coords3[2] = 0.0F; 2843 break; 2844 2845 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2846 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2847 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2848 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2849 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2850 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2851 /* loop over quad verts */ 2852 for (i = 0; i < 4; i++) { 2853 /* Compute sc = +/-scale and tc = +/-scale. 2854 * Not +/-1 to avoid cube face selection ambiguity near the edges, 2855 * though that can still sometimes happen with this scale factor... 2856 */ 2857 const GLfloat scale = 0.9999f; 2858 const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale; 2859 const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale; 2860 GLfloat *coord; 2861 2862 switch (i) { 2863 case 0: 2864 coord = coords0; 2865 break; 2866 case 1: 2867 coord = coords1; 2868 break; 2869 case 2: 2870 coord = coords2; 2871 break; 2872 case 3: 2873 coord = coords3; 2874 break; 2875 default: 2876 assert(0); 2877 } 2878 2879 switch (faceTarget) { 2880 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2881 coord[0] = 1.0f; 2882 coord[1] = -tc; 2883 coord[2] = -sc; 2884 break; 2885 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2886 coord[0] = -1.0f; 2887 coord[1] = -tc; 2888 coord[2] = sc; 2889 break; 2890 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2891 coord[0] = sc; 2892 coord[1] = 1.0f; 2893 coord[2] = tc; 2894 break; 2895 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2896 coord[0] = sc; 2897 coord[1] = -1.0f; 2898 coord[2] = -tc; 2899 break; 2900 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2901 coord[0] = sc; 2902 coord[1] = -tc; 2903 coord[2] = 1.0f; 2904 break; 2905 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2906 coord[0] = -sc; 2907 coord[1] = -tc; 2908 coord[2] = -1.0f; 2909 break; 2910 default: 2911 assert(0); 2912 } 2913 } 2914 break; 2915 default: 2916 assert(0 && "unexpected target in meta setup_texture_coords()"); 2917 } 2918} 2919 2920 2921static void 2922setup_ff_generate_mipmap(struct gl_context *ctx, 2923 struct gen_mipmap_state *mipmap) 2924{ 2925 struct vertex { 2926 GLfloat x, y, tex[3]; 2927 }; 2928 2929 if (mipmap->ArrayObj == 0) { 2930 /* one-time setup */ 2931 /* create vertex array object */ 2932 _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj); 2933 _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj); 2934 2935 /* create vertex array buffer */ 2936 _mesa_GenBuffersARB(1, &mipmap->VBO); 2937 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO); 2938 /* setup vertex arrays */ 2939 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2940 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); 2941 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2942 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2943 } 2944 2945 /* setup projection matrix */ 2946 _mesa_MatrixMode(GL_PROJECTION); 2947 _mesa_LoadIdentity(); 2948 _mesa_Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 2949} 2950 2951 2952static void 2953setup_glsl_generate_mipmap(struct gl_context *ctx, 2954 struct gen_mipmap_state *mipmap) 2955{ 2956 struct vertex { 2957 GLfloat x, y, tex[3]; 2958 }; 2959 2960 static const char *vs_source = 2961 "attribute vec2 position;\n" 2962 "attribute vec3 textureCoords;\n" 2963 "varying vec3 texCoords;\n" 2964 "void main()\n" 2965 "{\n" 2966 " texCoords = textureCoords;\n" 2967 " gl_Position = vec4(position, 0.0, 1.0);\n" 2968 "}\n"; 2969 static const char *fs_source = 2970 "uniform sampler2D tex2d;\n" 2971 "varying vec3 texCoords;\n" 2972 "void main()\n" 2973 "{\n" 2974 " gl_FragColor = texture2D(tex2d, texCoords.xy);\n" 2975 "}\n"; 2976 2977 static const char *vs_int_source = 2978 "#version 130\n" 2979 "in vec2 position;\n" 2980 "in vec3 textureCoords;\n" 2981 "out vec3 texCoords;\n" 2982 "void main()\n" 2983 "{\n" 2984 " texCoords = textureCoords;\n" 2985 " gl_Position = gl_Vertex;\n" 2986 "}\n"; 2987 static const char *fs_int_source = 2988 "#version 130\n" 2989 "uniform isampler2D tex2d;\n" 2990 "in vec3 texCoords;\n" 2991 "out ivec4 out_color;\n" 2992 "\n" 2993 "void main()\n" 2994 "{\n" 2995 " out_color = texture(tex2d, texCoords.xy);\n" 2996 "}\n"; 2997 GLuint vs, fs; 2998 2999 /* Check if already initialized */ 3000 if (mipmap->ArrayObj != 0) 3001 return; 3002 /* create vertex array object */ 3003 _mesa_GenVertexArrays(1, &mipmap->ArrayObj); 3004 _mesa_BindVertexArray(mipmap->ArrayObj); 3005 3006 /* create vertex array buffer */ 3007 _mesa_GenBuffersARB(1, &mipmap->VBO); 3008 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO); 3009 3010 /* setup vertex arrays */ 3011 _mesa_VertexAttribPointerARB(0, 2, GL_FLOAT, GL_FALSE, 3012 sizeof(struct vertex), OFFSET(x)); 3013 _mesa_VertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE, 3014 sizeof(struct vertex), OFFSET(tex)); 3015 3016 vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); 3017 fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); 3018 3019 mipmap->ShaderProg = _mesa_CreateProgramObjectARB(); 3020 _mesa_AttachShader(mipmap->ShaderProg, fs); 3021 _mesa_DeleteObjectARB(fs); 3022 _mesa_AttachShader(mipmap->ShaderProg, vs); 3023 _mesa_DeleteObjectARB(vs); 3024 _mesa_BindAttribLocationARB(mipmap->ShaderProg, 0, "position"); 3025 _mesa_BindAttribLocationARB(mipmap->ShaderProg, 1, "texcoords"); 3026 _mesa_EnableVertexAttribArrayARB(0); 3027 _mesa_EnableVertexAttribArrayARB(1); 3028 link_program_with_debug(ctx, mipmap->ShaderProg); 3029 3030 if ((_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) || 3031 _mesa_is_gles3(ctx)){ 3032 vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source); 3033 fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source); 3034 3035 mipmap->IntegerShaderProg = _mesa_CreateProgramObjectARB(); 3036 _mesa_AttachShader(mipmap->IntegerShaderProg, fs); 3037 _mesa_DeleteObjectARB(fs); 3038 _mesa_AttachShader(mipmap->IntegerShaderProg, vs); 3039 _mesa_DeleteObjectARB(vs); 3040 _mesa_BindAttribLocationARB(mipmap->IntegerShaderProg, 0, "position"); 3041 _mesa_BindAttribLocationARB(mipmap->IntegerShaderProg, 1, "texcoords"); 3042 3043 /* Note that user-defined out attributes get automatically assigned 3044 * locations starting from 0, so we don't need to explicitly 3045 * BindFragDataLocation to 0. 3046 */ 3047 link_program_with_debug(ctx, mipmap->IntegerShaderProg); 3048 } 3049} 3050 3051 3052static void 3053meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, 3054 struct gen_mipmap_state *mipmap) 3055{ 3056 if (mipmap->ArrayObj == 0) 3057 return; 3058 _mesa_DeleteVertexArraysAPPLE(1, &mipmap->ArrayObj); 3059 mipmap->ArrayObj = 0; 3060 _mesa_DeleteBuffersARB(1, &mipmap->VBO); 3061 mipmap->VBO = 0; 3062 _mesa_DeleteObjectARB(mipmap->ShaderProg); 3063 mipmap->ShaderProg = 0; 3064 3065 if (mipmap->IntegerShaderProg) { 3066 _mesa_DeleteObjectARB(mipmap->IntegerShaderProg); 3067 mipmap->IntegerShaderProg = 0; 3068 } 3069} 3070 3071 3072/** 3073 * Called via ctx->Driver.GenerateMipmap() 3074 * Note: We don't yet support 3D textures, 1D/2D array textures or texture 3075 * borders. 3076 */ 3077void 3078_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, 3079 struct gl_texture_object *texObj) 3080{ 3081 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; 3082 struct vertex { 3083 GLfloat x, y, tex[3]; 3084 }; 3085 struct vertex verts[4]; 3086 const GLuint baseLevel = texObj->BaseLevel; 3087 const GLuint maxLevel = texObj->MaxLevel; 3088 const GLint maxLevelSave = texObj->MaxLevel; 3089 const GLboolean genMipmapSave = texObj->GenerateMipmap; 3090 const GLenum srgbBufferSave = ctx->Color.sRGBEnabled; 3091 const GLuint fboSave = ctx->DrawBuffer->Name; 3092 const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit; 3093 const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && 3094 ctx->Extensions.ARB_fragment_shader && 3095 (ctx->API != API_OPENGLES); 3096 GLenum faceTarget; 3097 GLuint dstLevel; 3098 const GLint slice = 0; 3099 GLuint samplerSave; 3100 3101 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { 3102 _mesa_generate_mipmap(ctx, target, texObj); 3103 return; 3104 } 3105 3106 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && 3107 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { 3108 faceTarget = target; 3109 target = GL_TEXTURE_CUBE_MAP; 3110 } 3111 else { 3112 faceTarget = target; 3113 } 3114 3115 _mesa_meta_begin(ctx, MESA_META_ALL); 3116 3117 /* Choose between glsl version and fixed function version of 3118 * GenerateMipmap function. 3119 */ 3120 if (use_glsl_version) { 3121 setup_glsl_generate_mipmap(ctx, mipmap); 3122 3123 if (texObj->_IsIntegerFormat) 3124 _mesa_UseProgramObjectARB(mipmap->IntegerShaderProg); 3125 else 3126 _mesa_UseProgramObjectARB(mipmap->ShaderProg); 3127 } 3128 else { 3129 setup_ff_generate_mipmap(ctx, mipmap); 3130 _mesa_set_enable(ctx, target, GL_TRUE); 3131 } 3132 3133 _mesa_BindVertexArray(mipmap->ArrayObj); 3134 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO); 3135 3136 samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? 3137 ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; 3138 3139 if (currentTexUnitSave != 0) 3140 _mesa_BindTexture(target, texObj->Name); 3141 3142 if (!mipmap->FBO) { 3143 _mesa_GenFramebuffersEXT(1, &mipmap->FBO); 3144 } 3145 3146 if (!mipmap->Sampler) { 3147 _mesa_GenSamplers(1, &mipmap->Sampler); 3148 _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); 3149 3150 if (use_glsl_version && texObj->_IsIntegerFormat) 3151 _mesa_SamplerParameteri(mipmap->Sampler, 3152 GL_TEXTURE_MIN_FILTER, 3153 GL_NEAREST_MIPMAP_NEAREST); 3154 else 3155 _mesa_SamplerParameteri(mipmap->Sampler, 3156 GL_TEXTURE_MIN_FILTER, 3157 GL_LINEAR_MIPMAP_LINEAR); 3158 3159 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 3160 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 3161 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 3162 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 3163 3164 /* We don't want to encode or decode sRGB values; treat them as linear. 3165 * This is not technically correct for GLES3 but we don't get any API 3166 * error at the moment. 3167 */ 3168 if (ctx->Extensions.EXT_texture_sRGB_decode) { 3169 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, 3170 GL_SKIP_DECODE_EXT); 3171 } 3172 3173 } else { 3174 _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); 3175 } 3176 3177 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO); 3178 3179 if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES) 3180 _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); 3181 else 3182 assert(!genMipmapSave); 3183 3184 if ((ctx->Extensions.EXT_framebuffer_sRGB && 3185 _mesa_is_desktop_gl(ctx)) || 3186 _mesa_is_gles3(ctx)) { 3187 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); 3188 } 3189 3190 /* Setup texture coordinates */ 3191 setup_texture_coords(faceTarget, 3192 slice, 3193 0, 0, /* width, height never used here */ 3194 verts[0].tex, 3195 verts[1].tex, 3196 verts[2].tex, 3197 verts[3].tex); 3198 3199 /* setup vertex positions */ 3200 verts[0].x = -1.0F; 3201 verts[0].y = -1.0F; 3202 verts[1].x = 1.0F; 3203 verts[1].y = -1.0F; 3204 verts[2].x = 1.0F; 3205 verts[2].y = 1.0F; 3206 verts[3].x = -1.0F; 3207 verts[3].y = 1.0F; 3208 3209 /* upload vertex data */ 3210 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 3211 verts, GL_DYNAMIC_DRAW_ARB); 3212 3213 /* texture is already locked, unlock now */ 3214 _mesa_unlock_texture(ctx, texObj); 3215 3216 for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { 3217 const struct gl_texture_image *srcImage; 3218 const GLuint srcLevel = dstLevel - 1; 3219 GLsizei srcWidth, srcHeight, srcDepth; 3220 GLsizei dstWidth, dstHeight, dstDepth; 3221 GLenum status; 3222 3223 srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); 3224 assert(srcImage->Border == 0); 3225 3226 /* src size */ 3227 srcWidth = srcImage->Width; 3228 srcHeight = srcImage->Height; 3229 srcDepth = srcImage->Depth; 3230 3231 /* new dst size */ 3232 dstWidth = MAX2(1, srcWidth / 2); 3233 dstHeight = MAX2(1, srcHeight / 2); 3234 dstDepth = MAX2(1, srcDepth / 2); 3235 3236 if (dstWidth == srcImage->Width && 3237 dstHeight == srcImage->Height && 3238 dstDepth == srcImage->Depth) { 3239 /* all done */ 3240 break; 3241 } 3242 3243 /* Allocate storage for the destination mipmap image(s) */ 3244 3245 /* Set MaxLevel large enough to hold the new level when we allocate it */ 3246 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); 3247 3248 if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel, 3249 dstWidth, dstHeight, dstDepth, 3250 srcImage->Border, 3251 srcImage->InternalFormat, 3252 srcImage->TexFormat)) { 3253 /* All done. We either ran out of memory or we would go beyond the 3254 * last valid level of an immutable texture if we continued. 3255 */ 3256 break; 3257 } 3258 3259 /* limit minification to src level */ 3260 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); 3261 3262 /* Set to draw into the current dstLevel */ 3263 if (target == GL_TEXTURE_1D) { 3264 _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, 3265 GL_COLOR_ATTACHMENT0_EXT, 3266 target, 3267 texObj->Name, 3268 dstLevel); 3269 } 3270 else if (target == GL_TEXTURE_3D) { 3271 GLint zoffset = 0; /* XXX unfinished */ 3272 _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, 3273 GL_COLOR_ATTACHMENT0_EXT, 3274 target, 3275 texObj->Name, 3276 dstLevel, zoffset); 3277 } 3278 else { 3279 /* 2D / cube */ 3280 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 3281 GL_COLOR_ATTACHMENT0_EXT, 3282 faceTarget, 3283 texObj->Name, 3284 dstLevel); 3285 } 3286 3287 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 3288 3289 /* sanity check */ 3290 status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 3291 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 3292 _mesa_problem(ctx, "Unexpected incomplete framebuffer in " 3293 "_mesa_meta_GenerateMipmap()"); 3294 break; 3295 } 3296 3297 assert(dstWidth == ctx->DrawBuffer->Width); 3298 assert(dstHeight == ctx->DrawBuffer->Height); 3299 3300 /* setup viewport */ 3301 _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight); 3302 3303 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 3304 } 3305 3306 if (ctx->Extensions.EXT_framebuffer_sRGB && srgbBufferSave) { 3307 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE); 3308 } 3309 3310 _mesa_lock_texture(ctx, texObj); /* relock */ 3311 3312 _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); 3313 3314 _mesa_meta_end(ctx); 3315 3316 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); 3317 if (genMipmapSave) 3318 _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); 3319 3320 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave); 3321} 3322 3323 3324/** 3325 * Determine the GL data type to use for the temporary image read with 3326 * ReadPixels() and passed to Tex[Sub]Image(). 3327 */ 3328static GLenum 3329get_temp_image_type(struct gl_context *ctx, gl_format format) 3330{ 3331 GLenum baseFormat; 3332 3333 baseFormat = _mesa_get_format_base_format(format); 3334 3335 switch (baseFormat) { 3336 case GL_RGBA: 3337 case GL_RGB: 3338 case GL_RG: 3339 case GL_RED: 3340 case GL_ALPHA: 3341 case GL_LUMINANCE: 3342 case GL_LUMINANCE_ALPHA: 3343 case GL_INTENSITY: 3344 if (ctx->DrawBuffer->Visual.redBits <= 8) 3345 return GL_UNSIGNED_BYTE; 3346 else if (ctx->DrawBuffer->Visual.redBits <= 16) 3347 return GL_UNSIGNED_SHORT; 3348 else 3349 return _mesa_get_format_datatype(format); 3350 case GL_DEPTH_COMPONENT: 3351 return GL_UNSIGNED_INT; 3352 case GL_DEPTH_STENCIL: 3353 return GL_UNSIGNED_INT_24_8; 3354 default: 3355 _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()", 3356 baseFormat); 3357 return 0; 3358 } 3359} 3360 3361 3362/** 3363 * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. 3364 * Have to be careful with locking and meta state for pixel transfer. 3365 */ 3366void 3367_mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, 3368 struct gl_texture_image *texImage, 3369 GLint xoffset, GLint yoffset, GLint zoffset, 3370 struct gl_renderbuffer *rb, 3371 GLint x, GLint y, 3372 GLsizei width, GLsizei height) 3373{ 3374 struct gl_texture_object *texObj = texImage->TexObject; 3375 GLenum format, type; 3376 GLint bpp; 3377 void *buf; 3378 3379 /* Choose format/type for temporary image buffer */ 3380 format = _mesa_get_format_base_format(texImage->TexFormat); 3381 if (format == GL_LUMINANCE || 3382 format == GL_LUMINANCE_ALPHA || 3383 format == GL_INTENSITY) { 3384 /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the 3385 * temp image buffer because glReadPixels will do L=R+G+B which is 3386 * not what we want (should be L=R). 3387 */ 3388 format = GL_RGBA; 3389 } 3390 3391 type = get_temp_image_type(ctx, texImage->TexFormat); 3392 if (_mesa_is_format_integer_color(texImage->TexFormat)) { 3393 format = _mesa_base_format_to_integer_format(format); 3394 } 3395 bpp = _mesa_bytes_per_pixel(format, type); 3396 if (bpp <= 0) { 3397 _mesa_problem(ctx, "Bad bpp in _mesa_meta_CopyTexSubImage()"); 3398 return; 3399 } 3400 3401 /* 3402 * Alloc image buffer (XXX could use a PBO) 3403 */ 3404 buf = malloc(width * height * bpp); 3405 if (!buf) { 3406 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims); 3407 return; 3408 } 3409 3410 _mesa_unlock_texture(ctx, texObj); /* need to unlock first */ 3411 3412 /* 3413 * Read image from framebuffer (disable pixel transfer ops) 3414 */ 3415 _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER); 3416 ctx->Driver.ReadPixels(ctx, x, y, width, height, 3417 format, type, &ctx->Pack, buf); 3418 _mesa_meta_end(ctx); 3419 3420 _mesa_update_state(ctx); /* to update pixel transfer state */ 3421 3422 /* 3423 * Store texture data (with pixel transfer ops) 3424 */ 3425 _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE); 3426 3427 ctx->Driver.TexSubImage(ctx, dims, texImage, 3428 xoffset, yoffset, zoffset, width, height, 1, 3429 format, type, buf, &ctx->Unpack); 3430 3431 _mesa_meta_end(ctx); 3432 3433 _mesa_lock_texture(ctx, texObj); /* re-lock */ 3434 3435 free(buf); 3436} 3437 3438 3439/** 3440 * Decompress a texture image by drawing a quad with the compressed 3441 * texture and reading the pixels out of the color buffer. 3442 * \param slice which slice of a 3D texture or layer of a 1D/2D texture 3443 * \param destFormat format, ala glReadPixels 3444 * \param destType type, ala glReadPixels 3445 * \param dest destination buffer 3446 * \param destRowLength dest image rowLength (ala GL_PACK_ROW_LENGTH) 3447 */ 3448static void 3449decompress_texture_image(struct gl_context *ctx, 3450 struct gl_texture_image *texImage, 3451 GLuint slice, 3452 GLenum destFormat, GLenum destType, 3453 GLvoid *dest) 3454{ 3455 struct decompress_state *decompress = &ctx->Meta->Decompress; 3456 struct gl_texture_object *texObj = texImage->TexObject; 3457 const GLint width = texImage->Width; 3458 const GLint height = texImage->Height; 3459 const GLenum target = texObj->Target; 3460 GLenum faceTarget; 3461 struct vertex { 3462 GLfloat x, y, tex[3]; 3463 }; 3464 struct vertex verts[4]; 3465 GLuint fboDrawSave, fboReadSave; 3466 GLuint rbSave; 3467 GLuint samplerSave; 3468 3469 if (slice > 0) { 3470 assert(target == GL_TEXTURE_3D || 3471 target == GL_TEXTURE_2D_ARRAY); 3472 } 3473 3474 if (target == GL_TEXTURE_CUBE_MAP) { 3475 faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; 3476 } 3477 else { 3478 faceTarget = target; 3479 } 3480 3481 /* save fbo bindings (not saved by _mesa_meta_begin()) */ 3482 fboDrawSave = ctx->DrawBuffer->Name; 3483 fboReadSave = ctx->ReadBuffer->Name; 3484 rbSave = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0; 3485 3486 _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_PIXEL_STORE); 3487 3488 samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? 3489 ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; 3490 3491 /* Create/bind FBO/renderbuffer */ 3492 if (decompress->FBO == 0) { 3493 _mesa_GenFramebuffersEXT(1, &decompress->FBO); 3494 _mesa_GenRenderbuffersEXT(1, &decompress->RBO); 3495 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO); 3496 _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO); 3497 _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, 3498 GL_COLOR_ATTACHMENT0_EXT, 3499 GL_RENDERBUFFER_EXT, 3500 decompress->RBO); 3501 } 3502 else { 3503 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO); 3504 } 3505 3506 /* alloc dest surface */ 3507 if (width > decompress->Width || height > decompress->Height) { 3508 _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO); 3509 _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, 3510 width, height); 3511 decompress->Width = width; 3512 decompress->Height = height; 3513 } 3514 3515 /* setup VBO data */ 3516 if (decompress->ArrayObj == 0) { 3517 /* create vertex array object */ 3518 _mesa_GenVertexArrays(1, &decompress->ArrayObj); 3519 _mesa_BindVertexArray(decompress->ArrayObj); 3520 3521 /* create vertex array buffer */ 3522 _mesa_GenBuffersARB(1, &decompress->VBO); 3523 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, decompress->VBO); 3524 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 3525 NULL, GL_DYNAMIC_DRAW_ARB); 3526 3527 /* setup vertex arrays */ 3528 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 3529 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); 3530 _mesa_EnableClientState(GL_VERTEX_ARRAY); 3531 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 3532 } 3533 else { 3534 _mesa_BindVertexArray(decompress->ArrayObj); 3535 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, decompress->VBO); 3536 } 3537 3538 if (!decompress->Sampler) { 3539 _mesa_GenSamplers(1, &decompress->Sampler); 3540 _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); 3541 /* nearest filtering */ 3542 _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3543 _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3544 /* No sRGB decode or encode.*/ 3545 if (ctx->Extensions.EXT_texture_sRGB_decode) { 3546 _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, 3547 GL_SKIP_DECODE_EXT); 3548 } 3549 3550 } else { 3551 _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); 3552 } 3553 3554 setup_texture_coords(faceTarget, slice, width, height, 3555 verts[0].tex, 3556 verts[1].tex, 3557 verts[2].tex, 3558 verts[3].tex); 3559 3560 /* setup vertex positions */ 3561 verts[0].x = 0.0F; 3562 verts[0].y = 0.0F; 3563 verts[1].x = width; 3564 verts[1].y = 0.0F; 3565 verts[2].x = width; 3566 verts[2].y = height; 3567 verts[3].x = 0.0F; 3568 verts[3].y = height; 3569 3570 /* upload new vertex data */ 3571 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 3572 3573 /* setup texture state */ 3574 _mesa_BindTexture(target, texObj->Name); 3575 _mesa_set_enable(ctx, target, GL_TRUE); 3576 3577 { 3578 /* save texture object state */ 3579 const GLint baseLevelSave = texObj->BaseLevel; 3580 const GLint maxLevelSave = texObj->MaxLevel; 3581 3582 /* restrict sampling to the texture level of interest */ 3583 if (target != GL_TEXTURE_RECTANGLE_ARB) { 3584 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, texImage->Level); 3585 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level); 3586 } 3587 3588 /* No sRGB decode or encode.*/ 3589 if (ctx->Extensions.EXT_framebuffer_sRGB) { 3590 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); 3591 } 3592 3593 /* render quad w/ texture into renderbuffer */ 3594 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 3595 3596 /* Restore texture object state, the texture binding will 3597 * be restored by _mesa_meta_end(). 3598 */ 3599 if (target != GL_TEXTURE_RECTANGLE_ARB) { 3600 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); 3601 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); 3602 } 3603 3604 } 3605 3606 /* read pixels from renderbuffer */ 3607 { 3608 GLenum baseTexFormat = texImage->_BaseFormat; 3609 3610 /* The pixel transfer state will be set to default values at this point 3611 * (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively 3612 * turned off (as required by glGetTexImage) but we need to handle some 3613 * special cases. In particular, single-channel texture values are 3614 * returned as red and two-channel texture values are returned as 3615 * red/alpha. 3616 */ 3617 if (baseTexFormat == GL_LUMINANCE || 3618 baseTexFormat == GL_LUMINANCE_ALPHA || 3619 baseTexFormat == GL_INTENSITY) { 3620 /* Green and blue must be zero */ 3621 _mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f); 3622 _mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f); 3623 } 3624 3625 _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest); 3626 } 3627 3628 /* disable texture unit */ 3629 _mesa_set_enable(ctx, target, GL_FALSE); 3630 3631 _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); 3632 3633 _mesa_meta_end(ctx); 3634 3635 /* restore fbo bindings */ 3636 if (fboDrawSave == fboReadSave) { 3637 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboDrawSave); 3638 } 3639 else { 3640 _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboDrawSave); 3641 _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fboReadSave); 3642 } 3643 _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbSave); 3644} 3645 3646 3647/** 3648 * This is just a wrapper around _mesa_get_tex_image() and 3649 * decompress_texture_image(). Meta functions should not be directly called 3650 * from core Mesa. 3651 */ 3652void 3653_mesa_meta_GetTexImage(struct gl_context *ctx, 3654 GLenum format, GLenum type, GLvoid *pixels, 3655 struct gl_texture_image *texImage) 3656{ 3657 /* We can only use the decompress-with-blit method here if the texels are 3658 * unsigned, normalized values. We could handle signed and unnormalized 3659 * with floating point renderbuffers... 3660 */ 3661 if (_mesa_is_format_compressed(texImage->TexFormat) && 3662 _mesa_get_format_datatype(texImage->TexFormat) 3663 == GL_UNSIGNED_NORMALIZED) { 3664 struct gl_texture_object *texObj = texImage->TexObject; 3665 const GLuint slice = 0; /* only 2D compressed textures for now */ 3666 /* Need to unlock the texture here to prevent deadlock... */ 3667 _mesa_unlock_texture(ctx, texObj); 3668 decompress_texture_image(ctx, texImage, slice, format, type, pixels); 3669 /* ... and relock it */ 3670 _mesa_lock_texture(ctx, texObj); 3671 } 3672 else { 3673 _mesa_get_teximage(ctx, format, type, pixels, texImage); 3674 } 3675} 3676 3677 3678/** 3679 * Meta implementation of ctx->Driver.DrawTex() in terms 3680 * of polygon rendering. 3681 */ 3682void 3683_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, 3684 GLfloat width, GLfloat height) 3685{ 3686#if FEATURE_OES_draw_texture 3687 struct drawtex_state *drawtex = &ctx->Meta->DrawTex; 3688 struct vertex { 3689 GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2]; 3690 }; 3691 struct vertex verts[4]; 3692 GLuint i; 3693 3694 _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | 3695 MESA_META_SHADER | 3696 MESA_META_TRANSFORM | 3697 MESA_META_VERTEX | 3698 MESA_META_VIEWPORT)); 3699 3700 if (drawtex->ArrayObj == 0) { 3701 /* one-time setup */ 3702 GLint active_texture; 3703 3704 /* create vertex array object */ 3705 _mesa_GenVertexArrays(1, &drawtex->ArrayObj); 3706 _mesa_BindVertexArray(drawtex->ArrayObj); 3707 3708 /* create vertex array buffer */ 3709 _mesa_GenBuffersARB(1, &drawtex->VBO); 3710 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO); 3711 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 3712 NULL, GL_DYNAMIC_DRAW_ARB); 3713 3714 /* client active texture is not part of the array object */ 3715 active_texture = ctx->Array.ActiveTexture; 3716 3717 /* setup vertex arrays */ 3718 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 3719 _mesa_EnableClientState(GL_VERTEX_ARRAY); 3720 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 3721 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i); 3722 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i])); 3723 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 3724 } 3725 3726 /* restore client active texture */ 3727 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture); 3728 } 3729 else { 3730 _mesa_BindVertexArray(drawtex->ArrayObj); 3731 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO); 3732 } 3733 3734 /* vertex positions, texcoords */ 3735 { 3736 const GLfloat x1 = x + width; 3737 const GLfloat y1 = y + height; 3738 3739 z = CLAMP(z, 0.0, 1.0); 3740 z = invert_z(z); 3741 3742 verts[0].x = x; 3743 verts[0].y = y; 3744 verts[0].z = z; 3745 3746 verts[1].x = x1; 3747 verts[1].y = y; 3748 verts[1].z = z; 3749 3750 verts[2].x = x1; 3751 verts[2].y = y1; 3752 verts[2].z = z; 3753 3754 verts[3].x = x; 3755 verts[3].y = y1; 3756 verts[3].z = z; 3757 3758 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 3759 const struct gl_texture_object *texObj; 3760 const struct gl_texture_image *texImage; 3761 GLfloat s, t, s1, t1; 3762 GLuint tw, th; 3763 3764 if (!ctx->Texture.Unit[i]._ReallyEnabled) { 3765 GLuint j; 3766 for (j = 0; j < 4; j++) { 3767 verts[j].st[i][0] = 0.0f; 3768 verts[j].st[i][1] = 0.0f; 3769 } 3770 continue; 3771 } 3772 3773 texObj = ctx->Texture.Unit[i]._Current; 3774 texImage = texObj->Image[0][texObj->BaseLevel]; 3775 tw = texImage->Width2; 3776 th = texImage->Height2; 3777 3778 s = (GLfloat) texObj->CropRect[0] / tw; 3779 t = (GLfloat) texObj->CropRect[1] / th; 3780 s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw; 3781 t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th; 3782 3783 verts[0].st[i][0] = s; 3784 verts[0].st[i][1] = t; 3785 3786 verts[1].st[i][0] = s1; 3787 verts[1].st[i][1] = t; 3788 3789 verts[2].st[i][0] = s1; 3790 verts[2].st[i][1] = t1; 3791 3792 verts[3].st[i][0] = s; 3793 verts[3].st[i][1] = t1; 3794 } 3795 3796 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 3797 } 3798 3799 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 3800 3801 _mesa_meta_end(ctx); 3802#endif /* FEATURE_OES_draw_texture */ 3803} 3804