1/* 2 * Copyright © 2013 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "main/mtypes.h" 25#include "main/macros.h" 26#include "main/samplerobj.h" 27#include "main/teximage.h" 28#include "main/texobj.h" 29 30#include "brw_context.h" 31#include "brw_mipmap_tree.h" 32#include "brw_tex.h" 33 34#define FILE_DEBUG_FLAG DEBUG_TEXTURE 35 36/** 37 * Sets our driver-specific variant of tObj->_MaxLevel for later surface state 38 * upload. 39 * 40 * If we're only ensuring that there is storage for the first miplevel of a 41 * texture, then in texture setup we're going to have to make sure we don't 42 * allow sampling beyond level 0. 43 */ 44static void 45brw_update_max_level(struct gl_texture_object *tObj, 46 struct gl_sampler_object *sampler) 47{ 48 struct brw_texture_object *brw_obj = brw_texture_object(tObj); 49 50 if (!tObj->_MipmapComplete || 51 (tObj->_RenderToTexture && 52 (sampler->Attrib.MinFilter == GL_NEAREST || 53 sampler->Attrib.MinFilter == GL_LINEAR))) { 54 brw_obj->_MaxLevel = tObj->Attrib.BaseLevel; 55 } else { 56 brw_obj->_MaxLevel = tObj->_MaxLevel; 57 } 58} 59 60/** 61 * At rendering-from-a-texture time, make sure that the texture object has a 62 * miptree that can hold the entire texture based on 63 * BaseLevel/MaxLevel/filtering, and copy in any texture images that are 64 * stored in other miptrees. 65 */ 66void 67brw_finalize_mipmap_tree(struct brw_context *brw, 68 struct gl_texture_object *tObj) 69{ 70 struct brw_texture_object *brw_obj = brw_texture_object(tObj); 71 GLuint face, i; 72 GLuint nr_faces = 0; 73 struct brw_texture_image *firstImage; 74 int width, height, depth; 75 76 /* TBOs require no validation -- they always just point to their BO. */ 77 if (tObj->Target == GL_TEXTURE_BUFFER) 78 return; 79 80 /* What levels does this validated texture image require? */ 81 int validate_first_level = tObj->Attrib.BaseLevel; 82 int validate_last_level = brw_obj->_MaxLevel; 83 84 /* Skip the loop over images in the common case of no images having 85 * changed. But if the GL_BASE_LEVEL or GL_MAX_LEVEL change to something we 86 * haven't looked at, then we do need to look at those new images. 87 */ 88 if (!brw_obj->needs_validate && 89 validate_first_level >= brw_obj->validated_first_level && 90 validate_last_level <= brw_obj->validated_last_level) { 91 return; 92 } 93 94 /* On recent generations, immutable textures should not get this far 95 * -- they should have been created in a validated state, and nothing 96 * can invalidate them. 97 * 98 * Unfortunately, this is not true on pre-Sandybridge hardware -- when 99 * rendering into an immutable-format depth texture we may have to rebase 100 * the rendered levels to meet alignment requirements. 101 * 102 * FINISHME: Avoid doing this. 103 */ 104 assert(!tObj->Immutable || brw->screen->devinfo.ver < 6); 105 106 firstImage = brw_texture_image(tObj->Image[0][tObj->Attrib.BaseLevel]); 107 if (!firstImage) 108 return; 109 110 /* Check tree can hold all active levels. Check tree matches 111 * target, imageFormat, etc. 112 */ 113 if (brw_obj->mt && 114 (!brw_miptree_match_image(brw_obj->mt, &firstImage->base.Base) || 115 validate_first_level < brw_obj->mt->first_level || 116 validate_last_level > brw_obj->mt->last_level)) { 117 brw_miptree_release(&brw_obj->mt); 118 } 119 120 121 /* May need to create a new tree: 122 */ 123 if (!brw_obj->mt) { 124 const unsigned level = firstImage->base.Base.Level; 125 brw_get_image_dims(&firstImage->base.Base, &width, &height, &depth); 126 /* Figure out image dimensions at start level. */ 127 switch(brw_obj->base.Target) { 128 case GL_TEXTURE_2D_MULTISAMPLE: 129 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 130 case GL_TEXTURE_RECTANGLE: 131 case GL_TEXTURE_EXTERNAL_OES: 132 assert(level == 0); 133 break; 134 case GL_TEXTURE_3D: 135 depth = depth << level; 136 FALLTHROUGH; 137 case GL_TEXTURE_2D: 138 case GL_TEXTURE_2D_ARRAY: 139 case GL_TEXTURE_CUBE_MAP: 140 case GL_TEXTURE_CUBE_MAP_ARRAY: 141 height = height << level; 142 FALLTHROUGH; 143 case GL_TEXTURE_1D: 144 case GL_TEXTURE_1D_ARRAY: 145 width = width << level; 146 break; 147 default: 148 unreachable("Unexpected target"); 149 } 150 perf_debug("Creating new %s %dx%dx%d %d-level miptree to handle " 151 "finalized texture miptree.\n", 152 _mesa_get_format_name(firstImage->base.Base.TexFormat), 153 width, height, depth, validate_last_level + 1); 154 155 brw_obj->mt = brw_miptree_create(brw, 156 brw_obj->base.Target, 157 firstImage->base.Base.TexFormat, 158 0, /* first_level */ 159 validate_last_level, 160 width, 161 height, 162 depth, 163 1 /* num_samples */, 164 MIPTREE_CREATE_BUSY); 165 if (!brw_obj->mt) 166 return; 167 } 168 169 /* Pull in any images not in the object's tree: 170 */ 171 nr_faces = _mesa_num_tex_faces(brw_obj->base.Target); 172 for (face = 0; face < nr_faces; face++) { 173 for (i = validate_first_level; i <= validate_last_level; i++) { 174 struct brw_texture_image *brw_image = 175 brw_texture_image(brw_obj->base.Image[face][i]); 176 /* skip too small size mipmap */ 177 if (brw_image == NULL) 178 break; 179 180 if (brw_obj->mt != brw_image->mt) 181 brw_miptree_copy_teximage(brw, brw_image, brw_obj->mt); 182 183 /* After we're done, we'd better agree that our layout is 184 * appropriate, or we'll end up hitting this function again on the 185 * next draw 186 */ 187 assert(brw_miptree_match_image(brw_obj->mt, &brw_image->base.Base)); 188 } 189 } 190 191 brw_obj->validated_first_level = validate_first_level; 192 brw_obj->validated_last_level = validate_last_level; 193 brw_obj->_Format = firstImage->base.Base.TexFormat, 194 brw_obj->needs_validate = false; 195} 196 197/** 198 * Finalizes all textures, completing any rendering that needs to be done 199 * to prepare them. 200 */ 201void 202brw_validate_textures(struct brw_context *brw) 203{ 204 struct gl_context *ctx = &brw->ctx; 205 const int max_enabled_unit = ctx->Texture._MaxEnabledTexImageUnit; 206 207 for (int unit = 0; unit <= max_enabled_unit; unit++) { 208 struct gl_texture_object *tex_obj = ctx->Texture.Unit[unit]._Current; 209 210 if (!tex_obj) 211 continue; 212 213 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit); 214 215 /* We know that this is true by now, and if it wasn't, we might have 216 * mismatched level sizes and the copies would fail. 217 */ 218 assert(tex_obj->_BaseComplete); 219 220 brw_update_max_level(tex_obj, sampler); 221 brw_finalize_mipmap_tree(brw, tex_obj); 222 } 223} 224