st_gen_mipmap.c revision 99fba5466bfd14c4e052041c0571821be529e762
10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong/************************************************************************** 20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * 30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * All Rights Reserved. 50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * 60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * Permission is hereby granted, free of charge, to any person obtaining a 70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * copy of this software and associated documentation files (the 80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * "Software"), to deal in the Software without restriction, including 90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * without limitation the rights to use, copy, modify, merge, publish, 100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * distribute, sub license, and/or sell copies of the Software, and to 110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * permit persons to whom the Software is furnished to do so, subject to 120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * the following conditions: 130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * 140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * The above copyright notice and this permission notice (including the 150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * next paragraph) shall be included in all copies or substantial portions 160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * of the Software. 170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * 180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * 260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong **************************************************************************/ 270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "main/imports.h" 300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "main/mipmap.h" 310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "main/teximage.h" 320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "main/texformat.h" 330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "shader/prog_instruction.h" 350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "pipe/p_context.h" 370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "pipe/p_defines.h" 380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "pipe/p_inlines.h" 390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "util/u_gen_mipmap.h" 400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "cso_cache/cso_cache.h" 420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "cso_cache/cso_context.h" 430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_context.h" 450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_draw.h" 460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_gen_mipmap.h" 470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_program.h" 480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_texture.h" 490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_cb_drawpixels.h" 500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "st_cb_texture.h" 510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong/** 540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * one-time init for generate mipmap 550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * XXX Note: there may be other times we need no-op/simple state like this. 560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * In that case, some code refactoring would be good. 570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong */ 580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid 590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongst_init_generate_mipmap(struct st_context *st) 600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong{ 610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong st->gen_mipmap = util_create_gen_mipmap(st->pipe, st->cso_context); 620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid 660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongst_destroy_generate_mipmap(struct st_context *st) 670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong{ 680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong util_destroy_gen_mipmap(st->gen_mipmap); 690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong st->gen_mipmap = NULL; 700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong/** 740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * Generate mipmap levels using hardware rendering. 750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong * \return TRUE if successful, FALSE if not possible 760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong */ 770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongstatic boolean 780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongst_render_mipmap(struct st_context *st, 790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong GLenum target, 800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_texture *pt, 810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong uint baseLevel, uint lastLevel) 820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong{ 830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_context *pipe = st->pipe; 840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_screen *screen = pipe->screen; 850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const uint face = _mesa_tex_target_to_face(target); 860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong assert(target != GL_TEXTURE_3D); /* not done yet */ 880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong /* check if we can render in the texture's format */ 900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) { 910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return FALSE; 920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel, 950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong PIPE_TEX_FILTER_LINEAR); 960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return TRUE; 980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongstatic void 1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongfallback_generate_mipmap(GLcontext *ctx, GLenum target, 1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct gl_texture_object *texObj) 1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong{ 1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_context *pipe = ctx->st->pipe; 1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_screen *screen = pipe->screen; 1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_texture *pt = st_get_texobj_texture(texObj); 1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const uint baseLevel = texObj->BaseLevel; 1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const uint lastLevel = pt->last_level; 1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const uint face = _mesa_tex_target_to_face(target), zslice = 0; 1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong uint dstLevel; 1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong GLenum datatype; 1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong GLuint comps; 1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong assert(target != GL_TEXTURE_3D); /* not done yet */ 1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat, 1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong &datatype, &comps); 1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { 1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const uint srcLevel = dstLevel - 1; 1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong struct pipe_surface *srcSurf, *dstSurf; 1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const ubyte *srcData; 1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ubyte *dstData; 1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); 1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); 1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong srcData = (ubyte *) pipe_buffer_map(pipe, srcSurf->buffer, 1300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong PIPE_BUFFER_USAGE_CPU_READ) 1310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong + srcSurf->offset; 1320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong dstData = (ubyte *) pipe_buffer_map(pipe, dstSurf->buffer, 1330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong PIPE_BUFFER_USAGE_CPU_WRITE) 134 + dstSurf->offset; 135 136 _mesa_generate_mipmap_level(target, datatype, comps, 137 0 /*border*/, 138 pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], 139 srcSurf->pitch * srcSurf->cpp, /* stride in bytes */ 140 srcData, 141 pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], 142 dstSurf->pitch * dstSurf->cpp, /* stride in bytes */ 143 dstData); 144 145 pipe_buffer_unmap(pipe, srcSurf->buffer); 146 pipe_buffer_unmap(pipe, dstSurf->buffer); 147 148 pipe_surface_reference(&srcSurf, NULL); 149 pipe_surface_reference(&dstSurf, NULL); 150 } 151} 152 153 154void 155st_generate_mipmap(GLcontext *ctx, GLenum target, 156 struct gl_texture_object *texObj) 157{ 158 struct st_context *st = ctx->st; 159 struct pipe_texture *pt = st_get_texobj_texture(texObj); 160 const uint baseLevel = texObj->BaseLevel; 161 const uint lastLevel = pt->last_level; 162 uint dstLevel; 163 164 if (!st_render_mipmap(st, target, pt, baseLevel, lastLevel)) { 165 fallback_generate_mipmap(ctx, target, texObj); 166 } 167 168 /* Fill in the Mesa gl_texture_image fields */ 169 for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { 170 const uint srcLevel = dstLevel - 1; 171 const struct gl_texture_image *srcImage 172 = _mesa_get_tex_image(ctx, texObj, target, srcLevel); 173 struct gl_texture_image *dstImage; 174 struct st_texture_image *stImage; 175 uint dstWidth = pt->width[dstLevel]; 176 uint dstHeight = pt->height[dstLevel]; 177 uint dstDepth = pt->depth[dstLevel]; 178 uint border = srcImage->Border; 179 180 dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel); 181 if (!dstImage) { 182 _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 183 return; 184 } 185 186 if (dstImage->ImageOffsets) 187 _mesa_free(dstImage->ImageOffsets); 188 189 /* Free old image data */ 190 if (dstImage->Data) 191 ctx->Driver.FreeTexImageData(ctx, dstImage); 192 193 /* initialize new image */ 194 _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, 195 dstDepth, border, srcImage->InternalFormat); 196 197 dstImage->TexFormat = srcImage->TexFormat; 198 199 stImage = (struct st_texture_image *) dstImage; 200 stImage->pt = pt; 201 } 202} 203