From 70e7905608b374f65d1f4b657f8ab61808c76ef6 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 5 Mar 2014 18:37:57 -0800 Subject: meta: Split GenerateMipmap() into its own file. Putting the implementation of each GL function in its own file makes it much easier not to get lost. Signed-off-by: Kenneth Graunke Reviewed-by: Matt Turner Reviewed-by: Anuj Phogat Reviewed-by: Ian Romanick --- src/mesa/drivers/common/meta.c | 338 +---------------------------------------- 1 file changed, 1 insertion(+), 337 deletions(-) (limited to 'src/mesa/drivers/common/meta.c') diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 2ac7867e63d..030e1116e9e 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -89,7 +89,6 @@ choose_blit_shader(GLenum target, struct blit_shader_table *table); 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); @@ -361,7 +360,7 @@ _mesa_meta_free(struct gl_context *ctx) _mesa_make_current(ctx, NULL, NULL); _mesa_meta_glsl_blit_cleanup(&ctx->Meta->Blit); meta_glsl_clear_cleanup(&ctx->Meta->Clear); - meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap); + _mesa_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); @@ -2360,102 +2359,6 @@ _mesa_meta_Bitmap(struct gl_context *ctx, _mesa_meta_end(ctx); } - -/** - * Check if the call to _mesa_meta_GenerateMipmap() will require a - * software fallback. The fallback path will require that the texture - * images are mapped. - * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise - */ -GLboolean -_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - const GLuint fboSave = ctx->DrawBuffer->Name; - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct gl_texture_image *baseImage; - GLuint srcLevel; - GLenum status; - - /* check for fallbacks */ - if (target == GL_TEXTURE_3D || - target == GL_TEXTURE_1D_ARRAY || - target == GL_TEXTURE_2D_ARRAY) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() to %s target\n", - _mesa_lookup_enum_by_nr(target)); - return GL_TRUE; - } - - srcLevel = texObj->BaseLevel; - baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); - if (!baseImage) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() couldn't find base teximage\n"); - return GL_TRUE; - } - - if (_mesa_is_format_compressed(baseImage->TexFormat)) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() with %s format\n", - _mesa_get_format_name(baseImage->TexFormat)); - return GL_TRUE; - } - - if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB && - !ctx->Extensions.EXT_texture_sRGB_decode) { - /* The texture format is sRGB but we can't turn off sRGB->linear - * texture sample conversion. So we won't be able to generate the - * right colors when rendering. Need to use a fallback. - */ - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() of sRGB texture without " - "sRGB decode\n"); - return GL_TRUE; - } - - /* - * Test that we can actually render in the texture's format. - */ - if (!mipmap->FBO) - _mesa_GenFramebuffers(1, &mipmap->FBO); - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); - - if (target == GL_TEXTURE_1D) { - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel); - } -#if 0 - /* other work is needed to enable 3D mipmap generation */ - else if (target == GL_TEXTURE_3D) { - GLint zoffset = 0; - _mesa_FramebufferTexture3D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel, zoffset); - } -#endif - else { - /* 2D / cube */ - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel); - } - - status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); - - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() got incomplete FBO\n"); - return GL_TRUE; - } - - return GL_FALSE; -} - - /** * Compute the texture coordinates for the four vertices of a quad for * drawing a 2D texture image or slice of a cube/3D texture. @@ -2698,245 +2601,6 @@ _mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table) table->sampler_cubemap_array.shader_prog = 0; } -static void -meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap) -{ - if (mipmap->VAO == 0) - return; - _mesa_DeleteVertexArrays(1, &mipmap->VAO); - mipmap->VAO = 0; - _mesa_DeleteBuffers(1, &mipmap->VBO); - mipmap->VBO = 0; - - _mesa_meta_blit_shader_table_cleanup(&mipmap->shaders); -} - - -/** - * Called via ctx->Driver.GenerateMipmap() - * Note: We don't yet support 3D textures, 1D/2D array textures or texture - * borders. - */ -void -_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct vertex verts[4]; - const GLuint baseLevel = texObj->BaseLevel; - const GLuint maxLevel = texObj->MaxLevel; - const GLint maxLevelSave = texObj->MaxLevel; - const GLboolean genMipmapSave = texObj->GenerateMipmap; - const GLuint fboSave = ctx->DrawBuffer->Name; - const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit; - const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader; - GLenum faceTarget; - GLuint dstLevel; - const GLint slice = 0; - GLuint samplerSave; - - if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { - _mesa_generate_mipmap(ctx, target, texObj); - return; - } - - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { - faceTarget = target; - target = GL_TEXTURE_CUBE_MAP; - } - else { - faceTarget = target; - } - - _mesa_meta_begin(ctx, MESA_META_ALL); - - /* Choose between glsl version and fixed function version of - * GenerateMipmap function. - */ - if (use_glsl_version) { - _mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, - 2, 3, 0); - _mesa_meta_setup_blit_shader(ctx, target, &mipmap->shaders); - } - else { - _mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); - _mesa_set_enable(ctx, target, GL_TRUE); - } - - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; - - if (currentTexUnitSave != 0) - _mesa_BindTexture(target, texObj->Name); - - if (!mipmap->FBO) { - _mesa_GenFramebuffers(1, &mipmap->FBO); - } - - if (!mipmap->Sampler) { - _mesa_GenSamplers(1, &mipmap->Sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - - _mesa_SamplerParameteri(mipmap->Sampler, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - /* We don't want to encode or decode sRGB values; treat them as linear. - * This is not technically correct for GLES3 but we don't get any API - * error at the moment. - */ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); - } - - } else { - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - } - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); - - _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* Setup texture coordinates */ - _mesa_meta_setup_texture_coords(faceTarget, - slice, - 0, 0, 1, /* width, height never used here */ - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); - - /* setup vertex positions */ - 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; - - /* upload vertex data */ - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - verts, GL_DYNAMIC_DRAW_ARB); - - /* texture is already locked, unlock now */ - _mesa_unlock_texture(ctx, texObj); - - for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { - const struct gl_texture_image *srcImage; - const GLuint srcLevel = dstLevel - 1; - GLsizei srcWidth, srcHeight, srcDepth; - GLsizei dstWidth, dstHeight, dstDepth; - GLenum status; - - srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); - assert(srcImage->Border == 0); - - /* src size */ - srcWidth = srcImage->Width; - srcHeight = srcImage->Height; - srcDepth = srcImage->Depth; - - /* new dst size */ - dstWidth = MAX2(1, srcWidth / 2); - dstHeight = MAX2(1, srcHeight / 2); - dstDepth = MAX2(1, srcDepth / 2); - - if (dstWidth == srcImage->Width && - dstHeight == srcImage->Height && - dstDepth == srcImage->Depth) { - /* all done */ - break; - } - - /* Allocate storage for the destination mipmap image(s) */ - - /* Set MaxLevel large enough to hold the new level when we allocate it */ - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); - - if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel, - dstWidth, dstHeight, dstDepth, - srcImage->Border, - srcImage->InternalFormat, - srcImage->TexFormat)) { - /* All done. We either ran out of memory or we would go beyond the - * last valid level of an immutable texture if we continued. - */ - break; - } - - /* limit minification to src level */ - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); - - /* Set to draw into the current dstLevel */ - if (target == GL_TEXTURE_1D) { - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texObj->Name, - dstLevel); - } - else if (target == GL_TEXTURE_3D) { - GLint zoffset = 0; /* XXX unfinished */ - _mesa_FramebufferTexture3D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texObj->Name, - dstLevel, zoffset); - } - else { - /* 2D / cube */ - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - faceTarget, - texObj->Name, - dstLevel); - } - - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - /* sanity check */ - status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_problem(ctx, "Unexpected incomplete framebuffer in " - "_mesa_meta_GenerateMipmap()"); - break; - } - - assert(dstWidth == ctx->DrawBuffer->Width); - assert(dstHeight == ctx->DrawBuffer->Height); - - /* setup viewport */ - _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - _mesa_lock_texture(ctx, texObj); /* relock */ - - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); - - _mesa_meta_end(ctx); - - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); - if (genMipmapSave) - _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); -} - - /** * Determine the GL data type to use for the temporary image read with * ReadPixels() and passed to Tex[Sub]Image(). -- cgit v1.2.3