Home | History | Annotate | Download | only in intel
      1 #include "main/mtypes.h"
      2 #include "main/macros.h"
      3 #include "main/samplerobj.h"
      4 #include "main/texobj.h"
      5 
      6 #include "intel_context.h"
      7 #include "intel_mipmap_tree.h"
      8 #include "intel_blit.h"
      9 #include "intel_tex.h"
     10 #include "intel_tex_layout.h"
     11 
     12 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
     13 
     14 /**
     15  * When validating, we only care about the texture images that could
     16  * be seen, so for non-mipmapped modes we want to ignore everything
     17  * but BaseLevel.
     18  */
     19 static void
     20 intel_update_max_level(struct intel_texture_object *intelObj,
     21 		       struct gl_sampler_object *sampler)
     22 {
     23    struct gl_texture_object *tObj = &intelObj->base;
     24 
     25    if (sampler->MinFilter == GL_NEAREST ||
     26        sampler->MinFilter == GL_LINEAR) {
     27       intelObj->_MaxLevel = tObj->BaseLevel;
     28    } else {
     29       intelObj->_MaxLevel = tObj->_MaxLevel;
     30    }
     31 }
     32 
     33 /*
     34  */
     35 GLuint
     36 intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
     37 {
     38    struct gl_context *ctx = &intel->ctx;
     39    struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
     40    struct intel_texture_object *intelObj = intel_texture_object(tObj);
     41    struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
     42    GLuint face, i;
     43    GLuint nr_faces = 0;
     44    struct intel_texture_image *firstImage;
     45    int width, height, depth;
     46 
     47    /* TBOs require no validation -- they always just point to their BO. */
     48    if (tObj->Target == GL_TEXTURE_BUFFER)
     49       return true;
     50 
     51    /* We know/require this is true by now:
     52     */
     53    assert(intelObj->base._BaseComplete);
     54 
     55    /* What levels must the tree include at a minimum?
     56     */
     57    intel_update_max_level(intelObj, sampler);
     58    firstImage = intel_texture_image(tObj->Image[0][tObj->BaseLevel]);
     59 
     60    /* Check tree can hold all active levels.  Check tree matches
     61     * target, imageFormat, etc.
     62     *
     63     * For pre-gen4, we have to match first_level == tObj->BaseLevel,
     64     * because we don't have the control that gen4 does to make min/mag
     65     * determination happen at a nonzero (hardware) baselevel.  Because
     66     * of that, we just always relayout on baselevel change.
     67     */
     68    if (intelObj->mt &&
     69        (!intel_miptree_match_image(intelObj->mt, &firstImage->base.Base) ||
     70 	intelObj->mt->first_level != tObj->BaseLevel ||
     71 	intelObj->mt->last_level < intelObj->_MaxLevel)) {
     72       intel_miptree_release(&intelObj->mt);
     73    }
     74 
     75 
     76    /* May need to create a new tree:
     77     */
     78    if (!intelObj->mt) {
     79       intel_miptree_get_dimensions_for_image(&firstImage->base.Base,
     80 					     &width, &height, &depth);
     81 
     82       intelObj->mt = intel_miptree_create(intel,
     83                                           intelObj->base.Target,
     84 					  firstImage->base.Base.TexFormat,
     85                                           tObj->BaseLevel,
     86                                           intelObj->_MaxLevel,
     87                                           width,
     88                                           height,
     89                                           depth,
     90 					  true,
     91                                           0 /* num_samples */,
     92                                           INTEL_MSAA_LAYOUT_NONE);
     93       if (!intelObj->mt)
     94          return false;
     95    }
     96 
     97    /* Pull in any images not in the object's tree:
     98     */
     99    nr_faces = _mesa_num_tex_faces(intelObj->base.Target);
    100    for (face = 0; face < nr_faces; face++) {
    101       for (i = tObj->BaseLevel; i <= intelObj->_MaxLevel; i++) {
    102          struct intel_texture_image *intelImage =
    103             intel_texture_image(intelObj->base.Image[face][i]);
    104 	 /* skip too small size mipmap */
    105  	 if (intelImage == NULL)
    106 		 break;
    107 
    108          if (intelObj->mt != intelImage->mt) {
    109             intel_miptree_copy_teximage(intel, intelImage, intelObj->mt);
    110          }
    111       }
    112    }
    113 
    114    return true;
    115 }
    116 
    117 /**
    118  * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
    119  */
    120 static void
    121 intel_tex_map_image_for_swrast(struct intel_context *intel,
    122 			       struct intel_texture_image *intel_image,
    123 			       GLbitfield mode)
    124 {
    125    int level;
    126    int face;
    127    struct intel_mipmap_tree *mt;
    128    unsigned int x, y;
    129 
    130    if (!intel_image || !intel_image->mt)
    131       return;
    132 
    133    level = intel_image->base.Base.Level;
    134    face = intel_image->base.Base.Face;
    135    mt = intel_image->mt;
    136 
    137    for (int i = 0; i < mt->level[level].depth; i++)
    138       intel_miptree_slice_resolve_depth(intel, mt, level, i);
    139 
    140    if (mt->target == GL_TEXTURE_3D ||
    141        mt->target == GL_TEXTURE_2D_ARRAY ||
    142        mt->target == GL_TEXTURE_1D_ARRAY) {
    143       int i;
    144 
    145       /* ImageOffsets[] is only used for swrast's fetch_texel_3d, so we can't
    146        * share code with the normal path.
    147        */
    148       for (i = 0; i < mt->level[level].depth; i++) {
    149 	 intel_miptree_get_image_offset(mt, level, face, i, &x, &y);
    150 	 intel_image->base.ImageOffsets[i] = x + y * mt->region->pitch;
    151       }
    152 
    153       DBG("%s \n", __FUNCTION__);
    154 
    155       intel_image->base.Map = intel_region_map(intel, mt->region, mode);
    156    } else {
    157       assert(intel_image->base.Base.Depth == 1);
    158       intel_miptree_get_image_offset(mt, level, face, 0, &x, &y);
    159 
    160       DBG("%s: (%d,%d) -> (%d, %d)/%d\n",
    161 	  __FUNCTION__, face, level, x, y, mt->region->pitch * mt->cpp);
    162 
    163       intel_image->base.Map = intel_region_map(intel, mt->region, mode) +
    164 	 (x + y * mt->region->pitch) * mt->cpp;
    165    }
    166 
    167    intel_image->base.RowStride = mt->region->pitch;
    168 }
    169 
    170 static void
    171 intel_tex_unmap_image_for_swrast(struct intel_context *intel,
    172 				 struct intel_texture_image *intel_image)
    173 {
    174    if (intel_image && intel_image->mt) {
    175       intel_region_unmap(intel, intel_image->mt->region);
    176       intel_image->base.Map = NULL;
    177    }
    178 }
    179 
    180 /**
    181  * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
    182  */
    183 void
    184 intel_tex_map_images(struct intel_context *intel,
    185 		     struct intel_texture_object *intelObj,
    186 		     GLbitfield mode)
    187 {
    188    GLuint nr_faces = _mesa_num_tex_faces(intelObj->base.Target);
    189    int i, face;
    190 
    191    DBG("%s\n", __FUNCTION__);
    192 
    193    for (i = intelObj->base.BaseLevel; i <= intelObj->_MaxLevel; i++) {
    194       for (face = 0; face < nr_faces; face++) {
    195 	 struct intel_texture_image *intel_image =
    196 	    intel_texture_image(intelObj->base.Image[face][i]);
    197 
    198 	 intel_tex_map_image_for_swrast(intel, intel_image, mode);
    199       }
    200    }
    201 }
    202 
    203 void
    204 intel_tex_unmap_images(struct intel_context *intel,
    205 		       struct intel_texture_object *intelObj)
    206 {
    207    GLuint nr_faces = _mesa_num_tex_faces(intelObj->base.Target);
    208    int i, face;
    209 
    210    for (i = intelObj->base.BaseLevel; i <= intelObj->_MaxLevel; i++) {
    211       for (face = 0; face < nr_faces; face++) {
    212 	 struct intel_texture_image *intel_image =
    213 	    intel_texture_image(intelObj->base.Image[face][i]);
    214 
    215 	 intel_tex_unmap_image_for_swrast(intel, intel_image);
    216       }
    217    }
    218 }
    219