Home | History | Annotate | Download | only in intel
      1 
      2 #include "main/glheader.h"
      3 #include "main/macros.h"
      4 #include "main/mfeatures.h"
      5 #include "main/mtypes.h"
      6 #include "main/enums.h"
      7 #include "main/bufferobj.h"
      8 #include "main/context.h"
      9 #include "main/formats.h"
     10 #include "main/pbo.h"
     11 #include "main/renderbuffer.h"
     12 #include "main/texcompress.h"
     13 #include "main/texgetimage.h"
     14 #include "main/texobj.h"
     15 #include "main/teximage.h"
     16 #include "main/texstore.h"
     17 
     18 #include "intel_context.h"
     19 #include "intel_mipmap_tree.h"
     20 #include "intel_buffer_objects.h"
     21 #include "intel_batchbuffer.h"
     22 #include "intel_tex.h"
     23 #include "intel_blit.h"
     24 #include "intel_fbo.h"
     25 #include "intel_span.h"
     26 
     27 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
     28 
     29 /* Work back from the specified level of the image to the baselevel and create a
     30  * miptree of that size.
     31  */
     32 struct intel_mipmap_tree *
     33 intel_miptree_create_for_teximage(struct intel_context *intel,
     34 				  struct intel_texture_object *intelObj,
     35 				  struct intel_texture_image *intelImage,
     36 				  bool expect_accelerated_upload)
     37 {
     38    GLuint firstLevel;
     39    GLuint lastLevel;
     40    int width, height, depth;
     41    GLuint i;
     42 
     43    intel_miptree_get_dimensions_for_image(&intelImage->base.Base,
     44                                           &width, &height, &depth);
     45 
     46    DBG("%s\n", __FUNCTION__);
     47 
     48    if (intelImage->base.Base.Level > intelObj->base.BaseLevel &&
     49        (width == 1 ||
     50         (intelObj->base.Target != GL_TEXTURE_1D && height == 1) ||
     51         (intelObj->base.Target == GL_TEXTURE_3D && depth == 1))) {
     52       /* For this combination, we're at some lower mipmap level and
     53        * some important dimension is 1.  We can't extrapolate up to a
     54        * likely base level width/height/depth for a full mipmap stack
     55        * from this info, so just allocate this one level.
     56        */
     57       firstLevel = intelImage->base.Base.Level;
     58       lastLevel = intelImage->base.Base.Level;
     59    } else {
     60       /* If this image disrespects BaseLevel, allocate from level zero.
     61        * Usually BaseLevel == 0, so it's unlikely to happen.
     62        */
     63       if (intelImage->base.Base.Level < intelObj->base.BaseLevel)
     64 	 firstLevel = 0;
     65       else
     66 	 firstLevel = intelObj->base.BaseLevel;
     67 
     68       /* Figure out image dimensions at start level. */
     69       for (i = intelImage->base.Base.Level; i > firstLevel; i--) {
     70 	 width <<= 1;
     71 	 if (height != 1)
     72 	    height <<= 1;
     73 	 if (depth != 1)
     74 	    depth <<= 1;
     75       }
     76 
     77       /* Guess a reasonable value for lastLevel.  This is probably going
     78        * to be wrong fairly often and might mean that we have to look at
     79        * resizable buffers, or require that buffers implement lazy
     80        * pagetable arrangements.
     81        */
     82       if ((intelObj->base.Sampler.MinFilter == GL_NEAREST ||
     83 	   intelObj->base.Sampler.MinFilter == GL_LINEAR) &&
     84 	  intelImage->base.Base.Level == firstLevel &&
     85 	  (intel->gen < 4 || firstLevel == 0)) {
     86 	 lastLevel = firstLevel;
     87       } else if (intelObj->base.Target == GL_TEXTURE_EXTERNAL_OES) {
     88 	 lastLevel = firstLevel;
     89       } else {
     90 	 lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
     91       }
     92    }
     93 
     94    return intel_miptree_create(intel,
     95 			       intelObj->base.Target,
     96 			       intelImage->base.Base.TexFormat,
     97 			       firstLevel,
     98 			       lastLevel,
     99 			       width,
    100 			       height,
    101 			       depth,
    102 			       expect_accelerated_upload,
    103                                0 /* num_samples */,
    104                                INTEL_MSAA_LAYOUT_NONE);
    105 }
    106 
    107 /* There are actually quite a few combinations this will work for,
    108  * more than what I've listed here.
    109  */
    110 static bool
    111 check_pbo_format(GLenum format, GLenum type,
    112                  gl_format mesa_format)
    113 {
    114    switch (mesa_format) {
    115    case MESA_FORMAT_ARGB8888:
    116       return (format == GL_BGRA && (type == GL_UNSIGNED_BYTE ||
    117 				    type == GL_UNSIGNED_INT_8_8_8_8_REV));
    118    case MESA_FORMAT_RGB565:
    119       return (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5);
    120    case MESA_FORMAT_L8:
    121       return (format == GL_LUMINANCE && type == GL_UNSIGNED_BYTE);
    122    case MESA_FORMAT_YCBCR:
    123       return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
    124    default:
    125       return false;
    126    }
    127 }
    128 
    129 
    130 /* XXX: Do this for TexSubImage also:
    131  */
    132 static bool
    133 try_pbo_upload(struct gl_context *ctx,
    134                struct gl_texture_image *image,
    135                const struct gl_pixelstore_attrib *unpack,
    136 	       GLenum format, GLenum type, const void *pixels)
    137 {
    138    struct intel_texture_image *intelImage = intel_texture_image(image);
    139    struct intel_context *intel = intel_context(ctx);
    140    struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
    141    GLuint src_offset, src_stride;
    142    GLuint dst_x, dst_y, dst_stride;
    143    drm_intel_bo *dst_buffer, *src_buffer;
    144 
    145    if (!_mesa_is_bufferobj(unpack->BufferObj))
    146       return false;
    147 
    148    DBG("trying pbo upload\n");
    149 
    150    if (intel->ctx._ImageTransferState ||
    151        unpack->SkipPixels || unpack->SkipRows) {
    152       DBG("%s: image transfer\n", __FUNCTION__);
    153       return false;
    154    }
    155 
    156    if (!check_pbo_format(format, type, intelImage->base.Base.TexFormat)) {
    157       DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
    158 	  __FUNCTION__, _mesa_get_format_name(intelImage->base.Base.TexFormat),
    159 	  format, type);
    160       return false;
    161    }
    162 
    163    ctx->Driver.AllocTextureImageBuffer(ctx, image);
    164 
    165    if (!intelImage->mt) {
    166       DBG("%s: no miptree\n", __FUNCTION__);
    167       return false;
    168    }
    169 
    170    dst_buffer = intelImage->mt->region->bo;
    171    src_buffer = intel_bufferobj_source(intel, pbo, 64, &src_offset);
    172    /* note: potential 64-bit ptr to 32-bit int cast */
    173    src_offset += (GLuint) (unsigned long) pixels;
    174 
    175    if (unpack->RowLength > 0)
    176       src_stride = unpack->RowLength;
    177    else
    178       src_stride = image->Width;
    179 
    180    intel_miptree_get_image_offset(intelImage->mt, intelImage->base.Base.Level,
    181 				  intelImage->base.Base.Face, 0,
    182 				  &dst_x, &dst_y);
    183 
    184    dst_stride = intelImage->mt->region->pitch;
    185 
    186    if (!intelEmitCopyBlit(intel,
    187 			  intelImage->mt->cpp,
    188 			  src_stride, src_buffer,
    189 			  src_offset, false,
    190 			  dst_stride, dst_buffer, 0,
    191 			  intelImage->mt->region->tiling,
    192 			  0, 0, dst_x, dst_y, image->Width, image->Height,
    193 			  GL_COPY)) {
    194       DBG("%s: blit failed\n", __FUNCTION__);
    195       return false;
    196    }
    197 
    198    DBG("%s: success\n", __FUNCTION__);
    199    return true;
    200 }
    201 
    202 static void
    203 intelTexImage(struct gl_context * ctx,
    204               GLuint dims,
    205               struct gl_texture_image *texImage,
    206               GLenum format, GLenum type, const void *pixels,
    207               const struct gl_pixelstore_attrib *unpack)
    208 {
    209    DBG("%s target %s level %d %dx%dx%d\n", __FUNCTION__,
    210        _mesa_lookup_enum_by_nr(texImage->TexObject->Target),
    211        texImage->Level, texImage->Width, texImage->Height, texImage->Depth);
    212 
    213    /* Attempt to use the blitter for PBO image uploads.
    214     */
    215    if (dims <= 2 &&
    216        try_pbo_upload(ctx, texImage, unpack, format, type, pixels)) {
    217       return;
    218    }
    219 
    220    DBG("%s: upload image %dx%dx%d pixels %p\n",
    221        __FUNCTION__, texImage->Width, texImage->Height, texImage->Depth,
    222        pixels);
    223 
    224    _mesa_store_teximage(ctx, dims, texImage,
    225                         format, type, pixels, unpack);
    226 }
    227 
    228 
    229 /**
    230  * Binds a region to a texture image, like it was uploaded by glTexImage2D().
    231  *
    232  * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
    233  */
    234 static void
    235 intel_set_texture_image_region(struct gl_context *ctx,
    236 			       struct gl_texture_image *image,
    237 			       struct intel_region *region,
    238 			       GLenum target,
    239 			       GLenum internalFormat,
    240 			       gl_format format,
    241                                uint32_t offset)
    242 {
    243    struct intel_context *intel = intel_context(ctx);
    244    struct intel_texture_image *intel_image = intel_texture_image(image);
    245    struct gl_texture_object *texobj = image->TexObject;
    246    struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
    247 
    248    _mesa_init_teximage_fields(&intel->ctx, image,
    249 			      region->width, region->height, 1,
    250 			      0, internalFormat, format);
    251 
    252    ctx->Driver.FreeTextureImageBuffer(ctx, image);
    253 
    254    intel_image->mt = intel_miptree_create_for_region(intel, target,
    255 						     image->TexFormat,
    256 						     region);
    257    if (intel_image->mt == NULL)
    258        return;
    259 
    260    intel_image->mt->offset = offset;
    261    intel_image->base.RowStride = region->pitch;
    262 
    263    /* Immediately validate the image to the object. */
    264    intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
    265 }
    266 
    267 void
    268 intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
    269 		   GLint texture_format,
    270 		   __DRIdrawable *dPriv)
    271 {
    272    struct gl_framebuffer *fb = dPriv->driverPrivate;
    273    struct intel_context *intel = pDRICtx->driverPrivate;
    274    struct gl_context *ctx = &intel->ctx;
    275    struct intel_texture_object *intelObj;
    276    struct intel_renderbuffer *rb;
    277    struct gl_texture_object *texObj;
    278    struct gl_texture_image *texImage;
    279    int level = 0, internalFormat = 0;
    280    gl_format texFormat = MESA_FORMAT_NONE;
    281 
    282    texObj = _mesa_get_current_tex_object(ctx, target);
    283    intelObj = intel_texture_object(texObj);
    284 
    285    if (!intelObj)
    286       return;
    287 
    288    if (dPriv->lastStamp != dPriv->dri2.stamp ||
    289        !pDRICtx->driScreenPriv->dri2.useInvalidate)
    290       intel_update_renderbuffers(pDRICtx, dPriv);
    291 
    292    rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    293    /* If the region isn't set, then intel_update_renderbuffers was unable
    294     * to get the buffers for the drawable.
    295     */
    296    if (!rb || !rb->mt)
    297       return;
    298 
    299    if (rb->mt->cpp == 4) {
    300       if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
    301          internalFormat = GL_RGB;
    302          texFormat = MESA_FORMAT_XRGB8888;
    303       }
    304       else {
    305          internalFormat = GL_RGBA;
    306          texFormat = MESA_FORMAT_ARGB8888;
    307       }
    308    } else if (rb->mt->cpp == 2) {
    309       internalFormat = GL_RGB;
    310       texFormat = MESA_FORMAT_RGB565;
    311    }
    312 
    313    _mesa_lock_texture(&intel->ctx, texObj);
    314    texImage = _mesa_get_tex_image(ctx, texObj, target, level);
    315    intel_set_texture_image_region(ctx, texImage, rb->mt->region, target,
    316 				  internalFormat, texFormat, 0);
    317    _mesa_unlock_texture(&intel->ctx, texObj);
    318 }
    319 
    320 void
    321 intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
    322 {
    323    /* The old interface didn't have the format argument, so copy our
    324     * implementation's behavior at the time.
    325     */
    326    intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
    327 }
    328 
    329 #if FEATURE_OES_EGL_image
    330 static void
    331 intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
    332 			      struct gl_texture_object *texObj,
    333 			      struct gl_texture_image *texImage,
    334 			      GLeglImageOES image_handle)
    335 {
    336    struct intel_context *intel = intel_context(ctx);
    337    __DRIscreen *screen;
    338    __DRIimage *image;
    339 
    340    screen = intel->intelScreen->driScrnPriv;
    341    image = screen->dri2.image->lookupEGLImage(screen, image_handle,
    342 					      screen->loaderPrivate);
    343    if (image == NULL)
    344       return;
    345 
    346    intel_set_texture_image_region(ctx, texImage, image->region,
    347 				  target, image->internal_format,
    348                                   image->format, image->offset);
    349 }
    350 #endif
    351 
    352 void
    353 intelInitTextureImageFuncs(struct dd_function_table *functions)
    354 {
    355    functions->TexImage = intelTexImage;
    356 
    357 #if FEATURE_OES_EGL_image
    358    functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
    359 #endif
    360 }
    361