X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fcommon%2Fmeta.c;h=f0cd5a0a8eb9bc946665611757642584c13891d3;hb=e48a6378c905ab7817fcd19e08c186a89a39e005;hp=7b41876b94594ddfffb7d5a83bd382d535e09927;hpb=bb354c6c279031dafc08029a62cd3e76a6c1ca71;p=mesa.git diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 7b41876b945..f0cd5a0a8eb 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -138,9 +138,7 @@ struct save_state GLboolean FragmentProgramEnabled; struct gl_fragment_program *FragmentProgram; GLboolean ATIFragmentShaderEnabled; - struct gl_shader_program *VertexShader; - struct gl_shader_program *GeometryShader; - struct gl_shader_program *FragmentShader; + struct gl_shader_program *Shader[MESA_SHADER_STAGES]; struct gl_shader_program *ActiveShader; /** MESA_META_STENCIL_TEST */ @@ -166,11 +164,11 @@ struct save_state GLuint EnvMode; /* unit[0] only */ /** MESA_META_VERTEX */ - struct gl_array_object *ArrayObj; + struct gl_vertex_array_object *VAO; struct gl_buffer_object *ArrayBufferObj; /** MESA_META_VIEWPORT */ - GLint ViewportX, ViewportY, ViewportW, ViewportH; + GLfloat ViewportX, ViewportY, ViewportW, ViewportH; GLclampd DepthNear, DepthFar; /** MESA_META_CLAMP_FRAGMENT_COLOR */ @@ -217,17 +215,40 @@ struct temp_texture GLfloat Sright, Ttop; /**< right, top texcoords */ }; +/** + * State for GLSL texture sampler which is used to generate fragment + * shader in _mesa_meta_generate_mipmap(). + */ +struct glsl_sampler { + const char *type; + const char *func; + const char *texcoords; + GLuint shader_prog; +}; + +/** + * Table of all sampler types and shaders for accessing them. + */ +struct sampler_table { + struct glsl_sampler sampler_1d; + struct glsl_sampler sampler_2d; + struct glsl_sampler sampler_3d; + struct glsl_sampler sampler_rect; + struct glsl_sampler sampler_cubemap; + struct glsl_sampler sampler_1d_array; + struct glsl_sampler sampler_2d_array; + struct glsl_sampler sampler_cubemap_array; +}; /** * State for glBlitFramebufer() */ struct blit_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO; GLuint DepthFP; - GLuint ShaderProg; - GLuint RectShaderProg; + struct sampler_table samplers; struct temp_texture depthTex; }; @@ -237,7 +258,7 @@ struct blit_state */ struct clear_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO; GLuint ShaderProg; GLint ColorLocation; @@ -254,7 +275,7 @@ struct clear_state */ struct copypix_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO; }; @@ -264,7 +285,8 @@ struct copypix_state */ struct drawpix_state { - GLuint ArrayObj; + GLuint VAO; + GLuint VBO; GLuint StencilFP; /**< Fragment program for drawing stencil images */ GLuint DepthFP; /**< Fragment program for drawing depth images */ @@ -276,38 +298,22 @@ struct drawpix_state */ struct bitmap_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO; struct temp_texture Tex; /**< separate texture from other meta ops */ }; -/** - * State for GLSL texture sampler which is used to generate fragment - * shader in _mesa_meta_generate_mipmap(). - */ -struct glsl_sampler { - const char *type; - const char *func; - const char *texcoords; - GLuint shader_prog; -}; - /** * State for _mesa_meta_generate_mipmap() */ struct gen_mipmap_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO; GLuint FBO; GLuint Sampler; - GLuint ShaderProg; - struct glsl_sampler sampler_1d; - struct glsl_sampler sampler_2d; - struct glsl_sampler sampler_3d; - struct glsl_sampler sampler_cubemap; - struct glsl_sampler sampler_1d_array; - struct glsl_sampler sampler_2d_array; + + struct sampler_table samplers; }; /** @@ -315,9 +321,11 @@ struct gen_mipmap_state */ struct decompress_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO, FBO, RBO, Sampler; GLint Width, Height; + + struct sampler_table samplers; }; /** @@ -325,7 +333,7 @@ struct decompress_state */ struct drawtex_state { - GLuint ArrayObj; + GLuint VAO; GLuint VBO; }; @@ -352,11 +360,21 @@ struct gl_meta_state struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */ }; -static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit); -static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex); -static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear); -static void meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, - struct gen_mipmap_state *mipmap); +struct vertex { + GLfloat x, y, z, tex[4]; + GLfloat r, g, b, a; +}; + +static struct glsl_sampler * +setup_texture_sampler(GLenum target, struct sampler_table *table); + +static void meta_glsl_blit_cleanup(struct blit_state *blit); +static void cleanup_temp_texture(struct temp_texture *tex); +static void meta_glsl_clear_cleanup(struct clear_state *clear); +static void meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap); +static void meta_decompress_cleanup(struct decompress_state *decompress); +static void meta_drawpix_cleanup(struct drawpix_state *drawpix); +static void sampler_table_cleanup(struct sampler_table *table); static GLuint compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source) @@ -385,7 +403,7 @@ compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB return 0; } - _mesa_GetProgramInfoLog(shader, size, NULL, info); + _mesa_GetShaderInfoLog(shader, size, NULL, info); _mesa_problem(ctx, "meta program compile failed:\n%s\n" "source:\n%s\n", @@ -425,6 +443,192 @@ link_program_with_debug(struct gl_context *ctx, GLuint program) return 0; } +/** + * Generate a generic shader to blit from a texture to a framebuffer + * + * \param ctx Current GL context + * \param texTarget Texture target that will be the source of the blit + * + * \returns a handle to a shader program on success or zero on failure. + */ +static void +setup_blit_shader(struct gl_context *ctx, + GLenum target, + struct sampler_table *table) +{ + const char *vs_source; + char *fs_source; + GLuint vs, fs; + void *const mem_ctx = ralloc_context(NULL); + struct glsl_sampler *sampler = + setup_texture_sampler(target, table); + + assert(sampler != NULL); + + if (sampler->shader_prog != 0) { + _mesa_UseProgram(sampler->shader_prog); + return; + } + + /* The version check is a little tricky. API is set to API_OPENGLES2 even + * for OpenGL ES 3.0 contexts, and GLSLVersion may be set to 140, for + * example, in an OpenGL ES 2.0 context. + */ + if ((ctx->API == API_OPENGLES2 && ctx->Version < 30) + || ctx->Const.GLSLVersion < 130) { + vs_source = + "attribute vec2 position;\n" + "attribute vec3 textureCoords;\n" + "varying vec4 texCoords;\n" + "void main()\n" + "{\n" + " texCoords = textureCoords;\n" + " gl_Position = vec4(position, 0.0, 1.0);\n" + "}\n"; + + fs_source = ralloc_asprintf(mem_ctx, + "#extension GL_EXT_texture_array : enable\n" + "#extension GL_ARB_texture_cube_map_array: enable\n" + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "uniform %s texSampler;\n" + "varying vec4 texCoords;\n" + "void main()\n" + "{\n" + " gl_FragColor = %s(texSampler, %s);\n" + " gl_FragDepth = gl_FragColor.x;\n" + "}\n", + sampler->type, + sampler->func, sampler->texcoords); + } + else { + vs_source = ralloc_asprintf(mem_ctx, + "#version %s\n" + "in vec2 position;\n" + "in vec4 textureCoords;\n" + "out vec4 texCoords;\n" + "void main()\n" + "{\n" + " texCoords = textureCoords;\n" + " gl_Position = vec4(position, 0.0, 1.0);\n" + "}\n", + _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); + fs_source = ralloc_asprintf(mem_ctx, + "#version %s\n" + "#extension GL_ARB_texture_cube_map_array: enable\n" + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "uniform %s texSampler;\n" + "in vec4 texCoords;\n" + "out vec4 out_color;\n" + "\n" + "void main()\n" + "{\n" + " out_color = texture(texSampler, %s);\n" + " gl_FragDepth = out_color.x;\n" + "}\n", + _mesa_is_desktop_gl(ctx) ? "130" : "300 es", + sampler->type, + sampler->texcoords); + } + + vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); + fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); + + sampler->shader_prog = _mesa_CreateProgramObjectARB(); + _mesa_AttachShader(sampler->shader_prog, fs); + _mesa_DeleteObjectARB(fs); + _mesa_AttachShader(sampler->shader_prog, vs); + _mesa_DeleteObjectARB(vs); + _mesa_BindAttribLocation(sampler->shader_prog, 0, "position"); + _mesa_BindAttribLocation(sampler->shader_prog, 1, "texcoords"); + link_program_with_debug(ctx, sampler->shader_prog); + ralloc_free(mem_ctx); + + _mesa_UseProgram(sampler->shader_prog); +} + +/** + * Configure vertex buffer and vertex array objects for tests + * + * Regardless of whether a new VAO and new VBO are created, the objects + * referenced by \c VAO and \c VBO will be bound into the GL state vector + * when this function terminates. + * + * \param VAO Storage for vertex array object handle. If 0, a new VAO + * will be created. + * \param VBO Storage for vertex buffer object handle. If 0, a new VBO + * will be created. The new VBO will have storage for 4 + * \c vertex structures. + * \param use_generic_attributes Should generic attributes 0 and 1 be used, + * or should traditional, fixed-function color and texture + * coordinate be used? + * \param vertex_size Number of components for attribute 0 / vertex. + * \param texcoord_size Number of components for attribute 1 / texture + * coordinate. If this is 0, attribute 1 will not be set or + * enabled. + * \param color_size Number of components for attribute 1 / primary color. + * If this is 0, attribute 1 will not be set or enabled. + * + * \note If \c use_generic_attributes is \c true, \c color_size must be zero. + * Use \c texcoord_size instead. + */ +static void +setup_vertex_objects(GLuint *VAO, GLuint *VBO, bool use_generic_attributes, + unsigned vertex_size, unsigned texcoord_size, + unsigned color_size) +{ + if (*VAO == 0) { + assert(*VBO == 0); + + /* create vertex array object */ + _mesa_GenVertexArrays(1, VAO); + _mesa_BindVertexArray(*VAO); + + /* create vertex array buffer */ + _mesa_GenBuffers(1, VBO); + _mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO); + _mesa_BufferData(GL_ARRAY_BUFFER, 4 * sizeof(struct vertex), NULL, + GL_DYNAMIC_DRAW); + + /* setup vertex arrays */ + if (use_generic_attributes) { + assert(color_size == 0); + + _mesa_VertexAttribPointer(0, vertex_size, GL_FLOAT, GL_FALSE, + sizeof(struct vertex), OFFSET(x)); + _mesa_EnableVertexAttribArray(0); + + if (texcoord_size > 0) { + _mesa_VertexAttribPointer(1, texcoord_size, GL_FLOAT, GL_FALSE, + sizeof(struct vertex), OFFSET(tex)); + _mesa_EnableVertexAttribArray(1); + } + } else { + _mesa_VertexPointer(vertex_size, GL_FLOAT, sizeof(struct vertex), + OFFSET(x)); + _mesa_EnableClientState(GL_VERTEX_ARRAY); + + if (texcoord_size > 0) { + _mesa_TexCoordPointer(texcoord_size, GL_FLOAT, + sizeof(struct vertex), OFFSET(tex)); + _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + if (color_size > 0) { + _mesa_ColorPointer(color_size, GL_FLOAT, + sizeof(struct vertex), OFFSET(r)); + _mesa_EnableClientState(GL_COLOR_ARRAY); + } + } + } else { + _mesa_BindVertexArray(*VAO); + _mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO); + } +} + /** * Initialize meta-ops for a context. * To be called once during context creation. @@ -447,10 +651,12 @@ _mesa_meta_free(struct gl_context *ctx) { GET_CURRENT_CONTEXT(old_context); _mesa_make_current(ctx, NULL, NULL); - meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit); - meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear); - meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap); - cleanup_temp_texture(ctx, &ctx->Meta->TempTex); + meta_glsl_blit_cleanup(&ctx->Meta->Blit); + meta_glsl_clear_cleanup(&ctx->Meta->Clear); + meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap); + cleanup_temp_texture(&ctx->Meta->TempTex); + meta_decompress_cleanup(&ctx->Meta->Decompress); + meta_drawpix_cleanup(&ctx->Meta->DrawPix); if (old_context) _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); else @@ -598,6 +804,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) } if (state & MESA_META_SHADER) { + int i; + if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_vertex_program) { save->VertexProgramEnabled = ctx->VertexProgram.Enabled; _mesa_reference_vertprog(ctx, &save->VertexProgram, @@ -617,12 +825,10 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE); } - _mesa_reference_shader_program(ctx, &save->VertexShader, - ctx->Shader.CurrentVertexProgram); - _mesa_reference_shader_program(ctx, &save->GeometryShader, - ctx->Shader.CurrentGeometryProgram); - _mesa_reference_shader_program(ctx, &save->FragmentShader, - ctx->Shader.CurrentFragmentProgram); + for (i = 0; i < MESA_SHADER_STAGES; i++) { + _mesa_reference_shader_program(ctx, &save->Shader[i], + ctx->Shader.CurrentProgram[i]); + } _mesa_reference_shader_program(ctx, &save->ActiveShader, ctx->Shader.ActiveProgram); @@ -728,8 +934,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) if (state & MESA_META_VERTEX) { /* save vertex array object state */ - _mesa_reference_array_object(ctx, &save->ArrayObj, - ctx->Array.ArrayObj); + _mesa_reference_vao(ctx, &save->VAO, + ctx->Array.VAO); _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, ctx->Array.ArrayBufferObj); /* set some default state? */ @@ -737,21 +943,21 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) if (state & MESA_META_VIEWPORT) { /* save viewport state */ - save->ViewportX = ctx->Viewport.X; - save->ViewportY = ctx->Viewport.Y; - save->ViewportW = ctx->Viewport.Width; - save->ViewportH = ctx->Viewport.Height; + save->ViewportX = ctx->ViewportArray[0].X; + save->ViewportY = ctx->ViewportArray[0].Y; + save->ViewportW = ctx->ViewportArray[0].Width; + save->ViewportH = ctx->ViewportArray[0].Height; /* set viewport to match window size */ - if (ctx->Viewport.X != 0 || - ctx->Viewport.Y != 0 || - ctx->Viewport.Width != ctx->DrawBuffer->Width || - ctx->Viewport.Height != ctx->DrawBuffer->Height) { - _mesa_set_viewport(ctx, 0, 0, + if (ctx->ViewportArray[0].X != 0 || + ctx->ViewportArray[0].Y != 0 || + ctx->ViewportArray[0].Width != (float) ctx->DrawBuffer->Width || + ctx->ViewportArray[0].Height != (float) ctx->DrawBuffer->Height) { + _mesa_set_viewport(ctx, 0, 0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); } /* save depth range state */ - save->DepthNear = ctx->Viewport.Near; - save->DepthFar = ctx->Viewport.Far; + save->DepthNear = ctx->ViewportArray[0].Near; + save->DepthFar = ctx->ViewportArray[0].Far; /* set depth range to default */ _mesa_DepthRange(0.0, 1.0); } @@ -829,6 +1035,7 @@ _mesa_meta_end(struct gl_context *ctx) { struct save_state *save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth - 1]; const GLbitfield state = save->SavedState; + int i; /* After starting a new occlusion query, initialize the results to the * values saved previously. The driver will then continue to increment @@ -933,9 +1140,17 @@ _mesa_meta_end(struct gl_context *ctx) } if (state & MESA_META_SCISSOR) { - _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled); - _mesa_Scissor(save->Scissor.X, save->Scissor.Y, - save->Scissor.Width, save->Scissor.Height); + unsigned i; + + for (i = 0; i < ctx->Const.MaxViewports; i++) { + _mesa_set_scissor(ctx, i, + save->Scissor.ScissorArray[i].X, + save->Scissor.ScissorArray[i].Y, + save->Scissor.ScissorArray[i].Width, + save->Scissor.ScissorArray[i].Height); + _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, + (save->Scissor.EnableFlags >> i) & 1); + } } if (state & MESA_META_SHADER) { @@ -960,23 +1175,24 @@ _mesa_meta_end(struct gl_context *ctx) save->ATIFragmentShaderEnabled); } - if (ctx->Extensions.ARB_vertex_shader) - _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader); + if (ctx->Extensions.ARB_vertex_shader) { + _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, + save->Shader[MESA_SHADER_VERTEX]); + } if (_mesa_has_geometry_shaders(ctx)) _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, - save->GeometryShader); + save->Shader[MESA_SHADER_GEOMETRY]); if (ctx->Extensions.ARB_fragment_shader) _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, - save->FragmentShader); + save->Shader[MESA_SHADER_FRAGMENT]); _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, save->ActiveShader); - _mesa_reference_shader_program(ctx, &save->VertexShader, NULL); - _mesa_reference_shader_program(ctx, &save->GeometryShader, NULL); - _mesa_reference_shader_program(ctx, &save->FragmentShader, NULL); + for (i = 0; i < MESA_SHADER_STAGES; i++) + _mesa_reference_shader_program(ctx, &save->Shader[i], NULL); _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL); } @@ -1084,16 +1300,16 @@ _mesa_meta_end(struct gl_context *ctx) _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL); /* restore vertex array object */ - _mesa_BindVertexArray(save->ArrayObj->Name); - _mesa_reference_array_object(ctx, &save->ArrayObj, NULL); + _mesa_BindVertexArray(save->VAO->Name); + _mesa_reference_vao(ctx, &save->VAO, NULL); } if (state & MESA_META_VIEWPORT) { - if (save->ViewportX != ctx->Viewport.X || - save->ViewportY != ctx->Viewport.Y || - save->ViewportW != ctx->Viewport.Width || - save->ViewportH != ctx->Viewport.Height) { - _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY, + if (save->ViewportX != ctx->ViewportArray[0].X || + save->ViewportY != ctx->ViewportArray[0].Y || + save->ViewportW != ctx->ViewportArray[0].Width || + save->ViewportH != ctx->ViewportArray[0].Height) { + _mesa_set_viewport(ctx, 0, save->ViewportX, save->ViewportY, save->ViewportW, save->ViewportH); } _mesa_DepthRange(save->DepthNear, save->DepthFar); @@ -1200,7 +1416,7 @@ init_temp_texture(struct gl_context *ctx, struct temp_texture *tex) } static void -cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex) +cleanup_temp_texture(struct temp_texture *tex) { if (!tex->TexObj) return; @@ -1368,7 +1584,6 @@ static void setup_drawpix_texture(struct gl_context *ctx, struct temp_texture *tex, GLboolean newTex, - GLenum texIntFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) @@ -1445,39 +1660,13 @@ init_blit_depth_pixels(struct gl_context *ctx) } static void -setup_ff_blit_framebuffer(struct gl_context *ctx, - struct blit_state *blit) +setup_ff_tnl_for_blit(GLuint *VAO, GLuint *VBO, unsigned texcoord_size) { - struct vertex { - GLfloat x, y, s, t; - }; - struct vertex verts[4]; - - if (blit->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &blit->ArrayObj); - _mesa_BindVertexArray(blit->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &blit->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } + setup_vertex_objects(VAO, VBO, false, 2, texcoord_size, 0); /* setup projection matrix */ _mesa_MatrixMode(GL_PROJECTION); _mesa_LoadIdentity(); - _mesa_Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - } static void @@ -1485,123 +1674,12 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx, struct blit_state *blit, GLenum target) { - struct vertex { - GLfloat x, y, s, t; - }; - struct vertex verts[4]; - const char *vs_source; - char *fs_source; - GLuint vs, fs; - void *mem_ctx; - GLuint ShaderProg; - GLboolean texture_2d = (target == GL_TEXTURE_2D); - /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */ - assert(_mesa_is_desktop_gl(ctx) || texture_2d); + assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D); - /* Check if already initialized */ - if (blit->ArrayObj == 0) { + setup_vertex_objects(&blit->VAO, &blit->VBO, true, 2, 2, 0); - /* create vertex array object */ - _mesa_GenVertexArrays(1, &blit->ArrayObj); - _mesa_BindVertexArray(blit->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &blit->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(x)); - _mesa_VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(s)); - - _mesa_EnableVertexAttribArray(0); - _mesa_EnableVertexAttribArray(1); - } - - /* Generate a relevant fragment shader program for the texture target */ - if ((target == GL_TEXTURE_2D && blit->ShaderProg != 0) || - (target == GL_TEXTURE_RECTANGLE && blit->RectShaderProg != 0)) { - return; - } - - mem_ctx = ralloc_context(NULL); - - if (ctx->Const.GLSLVersion < 130) { - vs_source = - "attribute vec2 position;\n" - "attribute vec2 textureCoords;\n" - "varying vec2 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n"; - - fs_source = ralloc_asprintf(mem_ctx, - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "varying vec2 texCoords;\n" - "void main()\n" - "{\n" - " gl_FragColor = %s(texSampler, texCoords);\n" - " gl_FragDepth = gl_FragColor.r;\n" - "}\n", - texture_2d ? "sampler2D" : "sampler2DRect", - texture_2d ? "texture2D" : "texture2DRect"); - } - else { - vs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "in vec2 position;\n" - "in vec2 textureCoords;\n" - "out vec2 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); - fs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "in vec2 texCoords;\n" - "out vec4 out_color;\n" - "\n" - "void main()\n" - "{\n" - " out_color = %s(texSampler, texCoords);\n" - " gl_FragDepth = out_color.r;\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es", - texture_2d ? "sampler2D" : "sampler2DRect", - texture_2d ? "texture" : "texture2DRect"); - } - - vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); - fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); - - ShaderProg = _mesa_CreateProgramObjectARB(); - _mesa_AttachShader(ShaderProg, fs); - _mesa_DeleteObjectARB(fs); - _mesa_AttachShader(ShaderProg, vs); - _mesa_DeleteObjectARB(vs); - _mesa_BindAttribLocation(ShaderProg, 0, "position"); - _mesa_BindAttribLocation(ShaderProg, 1, "texcoords"); - link_program_with_debug(ctx, ShaderProg); - ralloc_free(mem_ctx); - if (texture_2d) - blit->ShaderProg = ShaderProg; - else - blit->RectShaderProg = ShaderProg; + setup_blit_shader(ctx, target, &blit->samplers); } /** @@ -1668,18 +1746,13 @@ blitframebuffer_texture(struct gl_context *ctx, */ if (glsl_version) { setup_glsl_blit_framebuffer(ctx, blit, target); - if (target == GL_TEXTURE_2D) - _mesa_UseProgram(blit->ShaderProg); - else - _mesa_UseProgram(blit->RectShaderProg); } else { - setup_ff_blit_framebuffer(ctx, &ctx->Meta->Blit); + setup_ff_tnl_for_blit(&ctx->Meta->Blit.VAO, + &ctx->Meta->Blit.VBO, + 2); } - _mesa_BindVertexArray(blit->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - _mesa_GenSamplers(1, &sampler); _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); @@ -1716,9 +1789,6 @@ blitframebuffer_texture(struct gl_context *ctx, /* Prepare vertex data (the VBO was previously created and bound) */ { - struct vertex { - GLfloat x, y, s, t; - }; struct vertex verts[4]; GLfloat s0, t0, s1, t1; @@ -1738,6 +1808,9 @@ blitframebuffer_texture(struct gl_context *ctx, t1 = (float) srcY1; } + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + /* setup vertex positions */ verts[0].x = -1.0F * flipX; verts[0].y = -1.0F * flipY; @@ -1748,20 +1821,20 @@ blitframebuffer_texture(struct gl_context *ctx, verts[3].x = -1.0F * flipX; verts[3].y = 1.0F * flipY; - verts[0].s = s0; - verts[0].t = t0; - verts[1].s = s1; - verts[1].t = t0; - verts[2].s = s1; - verts[2].t = t1; - verts[3].s = s0; - verts[3].t = t1; + verts[0].tex[0] = s0; + verts[0].tex[1] = t0; + verts[1].tex[0] = s1; + verts[1].tex[1] = t0; + verts[2].tex[0] = s1; + verts[2].tex[1] = t1; + verts[3].tex[0] = s0; + verts[3].tex[1] = t1; _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); } /* setup viewport */ - _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH); + _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH); _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); _mesa_DepthMask(GL_FALSE); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -1815,9 +1888,6 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, const GLint flipX = srcFlipX * dstFlipX; const GLint flipY = srcFlipY * dstFlipY; - struct vertex { - GLfloat x, y, s, t; - }; struct vertex verts[4]; GLboolean newTex; const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && @@ -1853,17 +1923,13 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, */ if (use_glsl_version) { setup_glsl_blit_framebuffer(ctx, blit, tex->Target); - if (tex->Target == GL_TEXTURE_2D) - _mesa_UseProgram(blit->ShaderProg); - else - _mesa_UseProgram(blit->RectShaderProg); } else { - setup_ff_blit_framebuffer(ctx, blit); + setup_ff_tnl_for_blit(&blit->VAO, &blit->VBO, 2); } - _mesa_BindVertexArray(blit->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); /* Continue with "normal" approach which involves copying the src rect * into a temporary texture and is "blitted" by drawing a textured quad. @@ -1903,20 +1969,20 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, rb_base_format, filter); /* texcoords (after texture allocation!) */ { - verts[0].s = 1.0F; - verts[0].t = 1.0F; - verts[1].s = tex->Sright - 1.0F; - verts[1].t = 1.0F; - verts[2].s = tex->Sright - 1.0F; - verts[2].t = tex->Ttop - 1.0F; - verts[3].s = 1.0F; - verts[3].t = tex->Ttop - 1.0F; + verts[0].tex[0] = 1.0F; + verts[0].tex[1] = 1.0F; + verts[1].tex[0] = tex->Sright - 1.0F; + verts[1].tex[1] = 1.0F; + verts[2].tex[0] = tex->Sright - 1.0F; + verts[2].tex[1] = tex->Ttop - 1.0F; + verts[3].tex[0] = 1.0F; + verts[3].tex[1] = tex->Ttop - 1.0F; /* upload new vertex data */ _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); } - _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH); + _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH); _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); _mesa_DepthMask(GL_FALSE); @@ -1936,20 +2002,20 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, newTex = alloc_texture(depthTex, srcW, srcH, GL_DEPTH_COMPONENT); _mesa_ReadPixels(srcX, srcY, srcW, srcH, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); - setup_drawpix_texture(ctx, depthTex, newTex, GL_DEPTH_COMPONENT, + setup_drawpix_texture(ctx, depthTex, newTex, srcW, srcH, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); /* texcoords (after texture allocation!) */ { - verts[0].s = 0.0F; - verts[0].t = 0.0F; - verts[1].s = depthTex->Sright; - verts[1].t = 0.0F; - verts[2].s = depthTex->Sright; - verts[2].t = depthTex->Ttop; - verts[3].s = 0.0F; - verts[3].t = depthTex->Ttop; + verts[0].tex[0] = 0.0F; + verts[0].tex[1] = 0.0F; + verts[1].tex[0] = depthTex->Sright; + verts[1].tex[1] = 0.0F; + verts[2].tex[0] = depthTex->Sright; + verts[2].tex[1] = depthTex->Ttop; + verts[3].tex[0] = 0.0F; + verts[3].tex[1] = depthTex->Ttop; /* upload new vertex data */ _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); @@ -1965,7 +2031,7 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, _mesa_DepthFunc(GL_ALWAYS); _mesa_DepthMask(GL_TRUE); - _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH); + _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH); _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); mask &= ~GL_DEPTH_BUFFER_BIT; @@ -1990,11 +2056,11 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, } static void -meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) +meta_glsl_blit_cleanup(struct blit_state *blit) { - if (blit->ArrayObj) { - _mesa_DeleteVertexArrays(1, &blit->ArrayObj); - blit->ArrayObj = 0; + if (blit->VAO) { + _mesa_DeleteVertexArrays(1, &blit->VAO); + blit->VAO = 0; _mesa_DeleteBuffers(1, &blit->VBO); blit->VBO = 0; } @@ -2003,10 +2069,7 @@ meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) blit->DepthFP = 0; } - _mesa_DeleteObjectARB(blit->ShaderProg); - blit->ShaderProg = 0; - _mesa_DeleteObjectARB(blit->RectShaderProg); - blit->RectShaderProg = 0; + sampler_table_cleanup(&blit->samplers); _mesa_DeleteTextures(1, &blit->depthTex.TexObj); blit->depthTex.TexObj = 0; @@ -2020,9 +2083,6 @@ void _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) { struct clear_state *clear = &ctx->Meta->Clear; - struct vertex { - GLfloat x, y, z, r, g, b, a; - }; struct vertex verts[4]; /* save all state but scissor, pixel pack/unpack */ GLbitfield metaSave = (MESA_META_ALL - @@ -2039,27 +2099,7 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) _mesa_meta_begin(ctx, metaSave); - if (clear->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &clear->ArrayObj); - _mesa_BindVertexArray(clear->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &clear->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_COLOR_ARRAY); - } - else { - _mesa_BindVertexArray(clear->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - } + setup_vertex_objects(&clear->VAO, &clear->VBO, false, 3, 0, 4); /* GL_COLOR_BUFFER_BIT */ if (buffers & BUFFER_BITS_COLOR) { @@ -2172,20 +2212,10 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) GLuint vs, gs = 0, fs; bool has_integer_textures; - if (clear->ArrayObj != 0) - return; - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &clear->ArrayObj); - _mesa_BindVertexArray(clear->ArrayObj); + setup_vertex_objects(&clear->VAO, &clear->VBO, true, 3, 0, 0); - /* create vertex array buffer */ - _mesa_GenBuffers(1, &clear->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - - /* setup vertex arrays */ - _mesa_VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); - _mesa_EnableVertexAttribArray(0); + if (clear->ShaderProg != 0) + return; vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER); _mesa_ShaderSource(vs, 1, &vs_source, NULL); @@ -2279,12 +2309,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) } static void -meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear) +meta_glsl_clear_cleanup(struct clear_state *clear) { - if (clear->ArrayObj == 0) + if (clear->VAO == 0) return; - _mesa_DeleteVertexArrays(1, &clear->ArrayObj); - clear->ArrayObj = 0; + _mesa_DeleteVertexArrays(1, &clear->VAO); + clear->VAO = 0; _mesa_DeleteBuffers(1, &clear->VBO); clear->VBO = 0; _mesa_DeleteObjectARB(clear->ShaderProg); @@ -2311,9 +2341,7 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) const float x1 = ((float)fb->_Xmax / fb->Width) * 2.0f - 1.0f; const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f; const float z = -invert_z(ctx->Depth.Clear); - struct vertex { - GLfloat x, y, z; - } verts[4]; + struct vertex verts[4]; metaSave = (MESA_META_ALPHA_TEST | MESA_META_BLEND | @@ -2349,9 +2377,6 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) ctx->Color.ClearColor.f); } - _mesa_BindVertexArray(clear->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - /* GL_COLOR_BUFFER_BIT */ if (buffers & BUFFER_BITS_COLOR) { /* leave colormask, glDrawBuffer state as-is */ @@ -2407,9 +2432,9 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) GL_DYNAMIC_DRAW_ARB); /* draw quad(s) */ - if (fb->NumLayers > 0) { + if (fb->MaxNumLayers > 0) { unsigned layer; - for (layer = 0; layer < fb->NumLayers; layer++) { + for (layer = 0; layer < fb->MaxNumLayers; layer++) { if (fb->_IntegerColor) _mesa_Uniform1i(clear->IntegerLayerLocation, layer); else @@ -2434,9 +2459,6 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, { struct copypix_state *copypix = &ctx->Meta->CopyPix; struct temp_texture *tex = get_temp_texture(ctx); - struct vertex { - GLfloat x, y, z, s, t; - }; struct vertex verts[4]; GLboolean newTex; GLenum intFormat = GL_RGBA; @@ -2462,32 +2484,13 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, MESA_META_VERTEX | MESA_META_VIEWPORT)); - if (copypix->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArrays(1, ©pix->ArrayObj); - _mesa_BindVertexArray(copypix->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, ©pix->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, copypix->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else { - _mesa_BindVertexArray(copypix->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, copypix->VBO); - } + setup_vertex_objects(©pix->VAO, ©pix->VBO, false, 3, 2, 0); newTex = alloc_texture(tex, width, height, intFormat); + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + /* vertex positions, texcoords (after texture allocation!) */ { const GLfloat dstX0 = (GLfloat) dstX; @@ -2499,23 +2502,23 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, verts[0].x = dstX0; verts[0].y = dstY0; verts[0].z = z; - verts[0].s = 0.0F; - verts[0].t = 0.0F; + verts[0].tex[0] = 0.0F; + verts[0].tex[1] = 0.0F; verts[1].x = dstX1; verts[1].y = dstY0; verts[1].z = z; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; + verts[1].tex[0] = tex->Sright; + verts[1].tex[1] = 0.0F; verts[2].x = dstX1; verts[2].y = dstY1; verts[2].z = z; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; + verts[2].tex[0] = tex->Sright; + verts[2].tex[1] = tex->Ttop; verts[3].x = dstX0; verts[3].y = dstY1; verts[3].z = z; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; + verts[3].tex[0] = 0.0F; + verts[3].tex[1] = tex->Ttop; /* upload new vertex data */ _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); @@ -2535,7 +2538,27 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, _mesa_meta_end(ctx); } +static void +meta_drawpix_cleanup(struct drawpix_state *drawpix) +{ + if (drawpix->VAO != 0) { + _mesa_DeleteVertexArrays(1, &drawpix->VAO); + drawpix->VAO = 0; + + _mesa_DeleteBuffers(1, &drawpix->VBO); + drawpix->VBO = 0; + } + + if (drawpix->StencilFP != 0) { + _mesa_DeleteProgramsARB(1, &drawpix->StencilFP); + drawpix->StencilFP = 0; + } + if (drawpix->DepthFP != 0) { + _mesa_DeleteProgramsARB(1, &drawpix->DepthFP); + drawpix->DepthFP = 0; + } +} /** * When the glDrawPixels() image size is greater than the max rectangle @@ -2688,14 +2711,10 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, struct temp_texture *tex = get_temp_texture(ctx); const struct gl_pixelstore_attrib unpackSave = ctx->Unpack; const GLuint origStencilMask = ctx->Stencil.WriteMask[0]; - struct vertex { - GLfloat x, y, z, s, t; - }; struct vertex verts[4]; GLenum texIntFormat; GLboolean fallback, newTex; GLbitfield metaExtraSave = 0x0; - GLuint vbo; /* * Determine if we can do the glDrawPixels with texture mapping. @@ -2787,6 +2806,11 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, newTex = alloc_texture(tex, width, height, texIntFormat); + setup_vertex_objects(&drawpix->VAO, &drawpix->VBO, false, 3, 2, 0); + + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + /* vertex positions, texcoords (after texture allocation!) */ { const GLfloat x0 = (GLfloat) x; @@ -2798,43 +2822,29 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, verts[0].x = x0; verts[0].y = y0; verts[0].z = z; - verts[0].s = 0.0F; - verts[0].t = 0.0F; + verts[0].tex[0] = 0.0F; + verts[0].tex[1] = 0.0F; verts[1].x = x1; verts[1].y = y0; verts[1].z = z; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; + verts[1].tex[0] = tex->Sright; + verts[1].tex[1] = 0.0F; verts[2].x = x1; verts[2].y = y1; verts[2].z = z; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; + verts[2].tex[0] = tex->Sright; + verts[2].tex[1] = tex->Ttop; verts[3].x = x0; verts[3].y = y1; verts[3].z = z; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; - } - - if (drawpix->ArrayObj == 0) { - /* one-time setup: create vertex array object */ - _mesa_GenVertexArrays(1, &drawpix->ArrayObj); + verts[3].tex[0] = 0.0F; + verts[3].tex[1] = tex->Ttop; } - _mesa_BindVertexArray(drawpix->ArrayObj); - /* create vertex array buffer */ - _mesa_GenBuffers(1, &vbo); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, vbo); + /* upload new vertex data */ _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, GL_DYNAMIC_DRAW_ARB); - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - /* set given unpack params */ ctx->Unpack = *unpack; @@ -2847,7 +2857,7 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, if (!drawpix->StencilFP) init_draw_stencil_pixels(ctx); - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, + setup_drawpix_texture(ctx, tex, newTex, width, height, GL_ALPHA, type, pixels); _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); @@ -2890,22 +2900,20 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, ctx->Current.RasterColor); - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, + setup_drawpix_texture(ctx, tex, newTex, width, height, format, type, pixels); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); } else { /* Drawing RGBA */ - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, + setup_drawpix_texture(ctx, tex, newTex, width, height, format, type, pixels); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); } _mesa_set_enable(ctx, tex->Target, GL_FALSE); - _mesa_DeleteBuffers(1, &vbo); - /* restore unpack params */ ctx->Unpack = unpackSave; @@ -2957,9 +2965,6 @@ _mesa_meta_Bitmap(struct gl_context *ctx, const GLenum texIntFormat = GL_ALPHA; const struct gl_pixelstore_attrib unpackSave = *unpack; GLubyte fg, bg; - struct vertex { - GLfloat x, y, z, s, t, r, g, b, a; - }; struct vertex verts[4]; GLboolean newTex; GLubyte *bitmap8; @@ -2993,34 +2998,13 @@ _mesa_meta_Bitmap(struct gl_context *ctx, MESA_META_VERTEX | MESA_META_VIEWPORT)); - if (bitmap->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj); - _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &bitmap->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, bitmap->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - _mesa_EnableClientState(GL_COLOR_ARRAY); - } - else { - _mesa_BindVertexArray(bitmap->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, bitmap->VBO); - } + setup_vertex_objects(&bitmap->VAO, &bitmap->VBO, false, 3, 2, 4); newTex = alloc_texture(tex, width, height, texIntFormat); + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + /* vertex positions, texcoords, colors (after texture allocation!) */ { const GLfloat x0 = (GLfloat) x; @@ -3033,23 +3017,23 @@ _mesa_meta_Bitmap(struct gl_context *ctx, verts[0].x = x0; verts[0].y = y0; verts[0].z = z; - verts[0].s = 0.0F; - verts[0].t = 0.0F; + verts[0].tex[0] = 0.0F; + verts[0].tex[1] = 0.0F; verts[1].x = x1; verts[1].y = y0; verts[1].z = z; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; + verts[1].tex[0] = tex->Sright; + verts[1].tex[1] = 0.0F; verts[2].x = x1; verts[2].y = y1; verts[2].z = z; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; + verts[2].tex[0] = tex->Sright; + verts[2].tex[1] = tex->Ttop; verts[3].x = x0; verts[3].y = y1; verts[3].z = z; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; + verts[3].tex[0] = 0.0F; + verts[3].tex[1] = tex->Ttop; for (i = 0; i < 4; i++) { verts[i].r = ctx->Current.RasterColor[0]; @@ -3083,7 +3067,7 @@ _mesa_meta_Bitmap(struct gl_context *ctx, _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE); _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg)); - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, + setup_drawpix_texture(ctx, tex, newTex, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -3209,10 +3193,10 @@ setup_texture_coords(GLenum faceTarget, GLint width, GLint height, GLint depth, - GLfloat coords0[3], - GLfloat coords1[3], - GLfloat coords2[3], - GLfloat coords3[3]) + GLfloat coords0[4], + GLfloat coords1[4], + GLfloat coords2[4], + GLfloat coords3[4]) { static const GLfloat st[4][2] = { {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} @@ -3220,6 +3204,13 @@ setup_texture_coords(GLenum faceTarget, GLuint i; GLfloat r; + /* Currently all texture targets want the W component to be 1.0. + */ + coords0[3] = 1.0F; + coords1[3] = 1.0F; + coords2[3] = 1.0F; + coords3[3] = 1.0F; + switch (faceTarget) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: @@ -3310,6 +3301,8 @@ setup_texture_coords(GLenum faceTarget, assert(0); } + coord[3] = (float) (slice / 6); + switch (faceTarget) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: coord[0] = 1.0f; @@ -3351,75 +3344,53 @@ setup_texture_coords(GLenum faceTarget, } } - -static void -setup_ff_generate_mipmap(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) -{ - struct vertex { - GLfloat x, y, tex[3]; - }; - - if (mipmap->ArrayObj == 0) { - /* one-time setup */ - /* create vertex array object */ - _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj); - _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &mipmap->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, mipmap->VBO); - /* setup vertex arrays */ - _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - /* setup projection matrix */ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadIdentity(); - _mesa_Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); -} - - static struct glsl_sampler * -setup_texture_sampler(GLenum target, struct gen_mipmap_state *mipmap) +setup_texture_sampler(GLenum target, struct sampler_table *table) { switch(target) { case GL_TEXTURE_1D: - mipmap->sampler_1d.type = "sampler1D"; - mipmap->sampler_1d.func = "texture1D"; - mipmap->sampler_1d.texcoords = "texCoords.x"; - return &mipmap->sampler_1d; + table->sampler_1d.type = "sampler1D"; + table->sampler_1d.func = "texture1D"; + table->sampler_1d.texcoords = "texCoords.x"; + return &table->sampler_1d; case GL_TEXTURE_2D: - mipmap->sampler_2d.type = "sampler2D"; - mipmap->sampler_2d.func = "texture2D"; - mipmap->sampler_2d.texcoords = "texCoords.xy"; - return &mipmap->sampler_2d; + table->sampler_2d.type = "sampler2D"; + table->sampler_2d.func = "texture2D"; + table->sampler_2d.texcoords = "texCoords.xy"; + return &table->sampler_2d; + case GL_TEXTURE_RECTANGLE: + table->sampler_rect.type = "sampler2DRect"; + table->sampler_rect.func = "texture2DRect"; + table->sampler_rect.texcoords = "texCoords.xy"; + return &table->sampler_rect; case GL_TEXTURE_3D: /* Code for mipmap generation with 3D textures is not used yet. * It's a sw fallback. */ - mipmap->sampler_3d.type = "sampler3D"; - mipmap->sampler_3d.func = "texture3D"; - mipmap->sampler_3d.texcoords = "texCoords"; - return &mipmap->sampler_3d; + table->sampler_3d.type = "sampler3D"; + table->sampler_3d.func = "texture3D"; + table->sampler_3d.texcoords = "texCoords.xyz"; + return &table->sampler_3d; case GL_TEXTURE_CUBE_MAP: - mipmap->sampler_cubemap.type = "samplerCube"; - mipmap->sampler_cubemap.func = "textureCube"; - mipmap->sampler_cubemap.texcoords = "texCoords"; - return &mipmap->sampler_cubemap; + table->sampler_cubemap.type = "samplerCube"; + table->sampler_cubemap.func = "textureCube"; + table->sampler_cubemap.texcoords = "texCoords.xyz"; + return &table->sampler_cubemap; case GL_TEXTURE_1D_ARRAY: - mipmap->sampler_1d_array.type = "sampler1DArray"; - mipmap->sampler_1d_array.func = "texture1DArray"; - mipmap->sampler_1d_array.texcoords = "texCoords.xy"; - return &mipmap->sampler_1d_array; + table->sampler_1d_array.type = "sampler1DArray"; + table->sampler_1d_array.func = "texture1DArray"; + table->sampler_1d_array.texcoords = "texCoords.xy"; + return &table->sampler_1d_array; case GL_TEXTURE_2D_ARRAY: - mipmap->sampler_2d_array.type = "sampler2DArray"; - mipmap->sampler_2d_array.func = "texture2DArray"; - mipmap->sampler_2d_array.texcoords = "texCoords"; - return &mipmap->sampler_2d_array; + table->sampler_2d_array.type = "sampler2DArray"; + table->sampler_2d_array.func = "texture2DArray"; + table->sampler_2d_array.texcoords = "texCoords.xyz"; + return &table->sampler_2d_array; + case GL_TEXTURE_CUBE_MAP_ARRAY: + table->sampler_cubemap_array.type = "samplerCubeArray"; + table->sampler_cubemap_array.func = "textureCubeArray"; + table->sampler_cubemap_array.texcoords = "texCoords.xyzw"; + return &table->sampler_cubemap_array; default: _mesa_problem(NULL, "Unexpected texture target 0x%x in" " setup_texture_sampler()\n", target); @@ -3427,146 +3398,50 @@ setup_texture_sampler(GLenum target, struct gen_mipmap_state *mipmap) } } +static void +sampler_table_cleanup(struct sampler_table *table) +{ + _mesa_DeleteObjectARB(table->sampler_1d.shader_prog); + _mesa_DeleteObjectARB(table->sampler_2d.shader_prog); + _mesa_DeleteObjectARB(table->sampler_3d.shader_prog); + _mesa_DeleteObjectARB(table->sampler_rect.shader_prog); + _mesa_DeleteObjectARB(table->sampler_cubemap.shader_prog); + _mesa_DeleteObjectARB(table->sampler_1d_array.shader_prog); + _mesa_DeleteObjectARB(table->sampler_2d_array.shader_prog); + _mesa_DeleteObjectARB(table->sampler_cubemap_array.shader_prog); + + table->sampler_1d.shader_prog = 0; + table->sampler_2d.shader_prog = 0; + table->sampler_3d.shader_prog = 0; + table->sampler_rect.shader_prog = 0; + table->sampler_cubemap.shader_prog = 0; + table->sampler_1d_array.shader_prog = 0; + table->sampler_2d_array.shader_prog = 0; + table->sampler_cubemap_array.shader_prog = 0; +} static void setup_glsl_generate_mipmap(struct gl_context *ctx, struct gen_mipmap_state *mipmap, GLenum target) { - struct vertex { - GLfloat x, y, tex[3]; - }; - struct glsl_sampler *sampler; - const char *vs_source; - char *fs_source; - GLuint vs, fs; - void *mem_ctx; - - /* Check if already initialized */ - if (mipmap->ArrayObj == 0) { - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &mipmap->ArrayObj); - _mesa_BindVertexArray(mipmap->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &mipmap->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, mipmap->VBO); + setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, 2, 3, 0); - /* setup vertex arrays */ - _mesa_VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(x)); - _mesa_VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(tex)); - _mesa_EnableVertexAttribArray(0); - _mesa_EnableVertexAttribArray(1); - } - - /* Generate a fragment shader program appropriate for the texture target */ - sampler = setup_texture_sampler(target, mipmap); - assert(sampler != NULL); - if (sampler->shader_prog != 0) { - mipmap->ShaderProg = sampler->shader_prog; - return; - } - - mem_ctx = ralloc_context(NULL); - - if (ctx->API == API_OPENGLES2 || ctx->Const.GLSLVersion < 130) { - vs_source = - "attribute vec2 position;\n" - "attribute vec3 textureCoords;\n" - "varying vec3 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n"; - - fs_source = ralloc_asprintf(mem_ctx, - "#extension GL_EXT_texture_array : enable\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "varying vec3 texCoords;\n" - "void main()\n" - "{\n" - " gl_FragColor = %s(texSampler, %s);\n" - "}\n", - sampler->type, - sampler->func, sampler->texcoords); - } - else { - vs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "in vec2 position;\n" - "in vec3 textureCoords;\n" - "out vec3 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); - fs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "in vec3 texCoords;\n" - "out vec4 out_color;\n" - "\n" - "void main()\n" - "{\n" - " out_color = texture(texSampler, %s);\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es", - sampler->type, - sampler->texcoords); - } - - vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); - fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); - - mipmap->ShaderProg = _mesa_CreateProgramObjectARB(); - _mesa_AttachShader(mipmap->ShaderProg, fs); - _mesa_DeleteObjectARB(fs); - _mesa_AttachShader(mipmap->ShaderProg, vs); - _mesa_DeleteObjectARB(vs); - _mesa_BindAttribLocation(mipmap->ShaderProg, 0, "position"); - _mesa_BindAttribLocation(mipmap->ShaderProg, 1, "texcoords"); - link_program_with_debug(ctx, mipmap->ShaderProg); - sampler->shader_prog = mipmap->ShaderProg; - ralloc_free(mem_ctx); + setup_blit_shader(ctx, target, &mipmap->samplers); } static void -meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) +meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap) { - if (mipmap->ArrayObj == 0) + if (mipmap->VAO == 0) return; - _mesa_DeleteVertexArrays(1, &mipmap->ArrayObj); - mipmap->ArrayObj = 0; + _mesa_DeleteVertexArrays(1, &mipmap->VAO); + mipmap->VAO = 0; _mesa_DeleteBuffers(1, &mipmap->VBO); mipmap->VBO = 0; - _mesa_DeleteObjectARB(mipmap->sampler_1d.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_2d.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_3d.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_cubemap.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_1d_array.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_2d_array.shader_prog); - - mipmap->sampler_1d.shader_prog = 0; - mipmap->sampler_2d.shader_prog = 0; - mipmap->sampler_3d.shader_prog = 0; - mipmap->sampler_cubemap.shader_prog = 0; - mipmap->sampler_1d_array.shader_prog = 0; - mipmap->sampler_2d_array.shader_prog = 0; + sampler_table_cleanup(&mipmap->samplers); } @@ -3580,9 +3455,6 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj) { struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct vertex { - GLfloat x, y, tex[3]; - }; struct vertex verts[4]; const GLuint baseLevel = texObj->BaseLevel; const GLuint maxLevel = texObj->MaxLevel; @@ -3619,16 +3491,12 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, */ if (use_glsl_version) { setup_glsl_generate_mipmap(ctx, mipmap, target); - _mesa_UseProgram(mipmap->ShaderProg); } else { - setup_ff_generate_mipmap(ctx, mipmap); + setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); _mesa_set_enable(ctx, target, GL_TRUE); } - _mesa_BindVertexArray(mipmap->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, mipmap->VBO); - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; @@ -3671,6 +3539,9 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, else assert(!genMipmapSave); + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + /* Setup texture coordinates */ setup_texture_coords(faceTarget, slice, @@ -3782,7 +3653,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, assert(dstHeight == ctx->DrawBuffer->Height); /* setup viewport */ - _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight); + _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -3806,7 +3677,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, * ReadPixels() and passed to Tex[Sub]Image(). */ static GLenum -get_temp_image_type(struct gl_context *ctx, gl_format format) +get_temp_image_type(struct gl_context *ctx, mesa_format format) { GLenum baseFormat; @@ -3870,6 +3741,12 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, GLint bpp; void *buf; + /* The gl_renderbuffer is part of the interface for + * dd_function_table::CopyTexSubImage, but this implementation does not use + * it. + */ + (void) rb; + /* Choose format/type for temporary image buffer */ format = _mesa_get_format_base_format(texImage->TexFormat); if (format == GL_LUMINANCE || @@ -3937,6 +3814,25 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, } +static void +meta_decompress_cleanup(struct decompress_state *decompress) +{ + if (decompress->FBO != 0) { + _mesa_DeleteFramebuffers(1, &decompress->FBO); + _mesa_DeleteRenderbuffers(1, &decompress->RBO); + } + + if (decompress->VAO != 0) { + _mesa_DeleteVertexArrays(1, &decompress->VAO); + _mesa_DeleteBuffers(1, &decompress->VBO); + } + + if (decompress->Sampler != 0) + _mesa_DeleteSamplers(1, &decompress->Sampler); + + memset(decompress, 0, sizeof(*decompress)); +} + /** * Decompress a texture image by drawing a quad with the compressed * texture and reading the pixels out of the color buffer. @@ -3960,24 +3856,41 @@ decompress_texture_image(struct gl_context *ctx, const GLint depth = texImage->Height; const GLenum target = texObj->Target; GLenum faceTarget; - struct vertex { - GLfloat x, y, tex[3]; - }; struct vertex verts[4]; GLuint fboDrawSave, fboReadSave; GLuint rbSave; GLuint samplerSave; + const bool use_glsl_version = ctx->Extensions.ARB_vertex_shader && + ctx->Extensions.ARB_fragment_shader && + (ctx->API != API_OPENGLES); if (slice > 0) { assert(target == GL_TEXTURE_3D || - target == GL_TEXTURE_2D_ARRAY); + target == GL_TEXTURE_2D_ARRAY || + target == GL_TEXTURE_CUBE_MAP_ARRAY); } - if (target == GL_TEXTURE_CUBE_MAP) { + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + assert(!"No compressed 1D textures."); + return; + + case GL_TEXTURE_3D: + assert(!"No compressed 3D textures."); + return; + + case GL_TEXTURE_CUBE_MAP_ARRAY: + faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (slice % 6); + break; + + case GL_TEXTURE_CUBE_MAP: faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; - } - else { + break; + + default: faceTarget = target; + break; } /* save fbo bindings (not saved by _mesa_meta_begin()) */ @@ -4014,27 +3927,13 @@ decompress_texture_image(struct gl_context *ctx, decompress->Height = height; } - /* setup VBO data */ - if (decompress->ArrayObj == 0) { - /* create vertex array object */ - _mesa_GenVertexArrays(1, &decompress->ArrayObj); - _mesa_BindVertexArray(decompress->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &decompress->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, decompress->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); + if (use_glsl_version) { + setup_vertex_objects(&decompress->VAO, &decompress->VBO, true, + 2, 4, 0); - /* setup vertex arrays */ - _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else { - _mesa_BindVertexArray(decompress->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, decompress->VBO); + setup_blit_shader(ctx, target, &decompress->samplers); + } else { + setup_ff_tnl_for_blit(&decompress->VAO, &decompress->VBO, 3); } if (!decompress->Sampler) { @@ -4053,6 +3952,9 @@ decompress_texture_image(struct gl_context *ctx, _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); } + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + setup_texture_coords(faceTarget, slice, width, height, depth, verts[0].tex, verts[1].tex, @@ -4060,26 +3962,25 @@ decompress_texture_image(struct gl_context *ctx, verts[3].tex); /* setup vertex positions */ - verts[0].x = 0.0F; - verts[0].y = 0.0F; - verts[1].x = width; - verts[1].y = 0.0F; - verts[2].x = width; - verts[2].y = height; - verts[3].x = 0.0F; - verts[3].y = height; + verts[0].x = -1.0F; + verts[0].y = -1.0F; + verts[1].x = 1.0F; + verts[1].y = -1.0F; + verts[2].x = 1.0F; + verts[2].y = 1.0F; + verts[3].x = -1.0F; + verts[3].y = 1.0F; - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadIdentity(); - _mesa_Ortho(0.0, width, 0.0, height, -1.0, 1.0); - _mesa_set_viewport(ctx, 0, 0, width, height); + _mesa_set_viewport(ctx, 0, 0, 0, width, height); /* upload new vertex data */ _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); /* setup texture state */ _mesa_BindTexture(target, texObj->Name); - _mesa_set_enable(ctx, target, GL_TRUE); + + if (!use_glsl_version) + _mesa_set_enable(ctx, target, GL_TRUE); { /* save texture object state */ @@ -4139,7 +4040,8 @@ decompress_texture_image(struct gl_context *ctx, } /* disable texture unit */ - _mesa_set_enable(ctx, target, GL_FALSE); + if (!use_glsl_version) + _mesa_set_enable(ctx, target, GL_FALSE); _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); @@ -4180,7 +4082,8 @@ _mesa_meta_GetTexImage(struct gl_context *ctx, _mesa_unlock_texture(ctx, texObj); for (slice = 0; slice < texImage->Depth; slice++) { void *dst; - if (texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) { + if (texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY + || texImage->TexObject->Target == GL_TEXTURE_CUBE_MAP_ARRAY) { /* Setup pixel packing. SkipPixels and SkipRows will be applied * in the decompress_texture_image() function's call to * glReadPixels but we need to compute the dest slice's address @@ -4228,13 +4131,13 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, MESA_META_VERTEX | MESA_META_VIEWPORT)); - if (drawtex->ArrayObj == 0) { + if (drawtex->VAO == 0) { /* one-time setup */ GLint active_texture; /* create vertex array object */ - _mesa_GenVertexArrays(1, &drawtex->ArrayObj); - _mesa_BindVertexArray(drawtex->ArrayObj); + _mesa_GenVertexArrays(1, &drawtex->VAO); + _mesa_BindVertexArray(drawtex->VAO); /* create vertex array buffer */ _mesa_GenBuffers(1, &drawtex->VBO); @@ -4258,7 +4161,7 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, _mesa_ClientActiveTexture(GL_TEXTURE0 + active_texture); } else { - _mesa_BindVertexArray(drawtex->ArrayObj); + _mesa_BindVertexArray(drawtex->VAO); _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO); }