diff options
author | Pauli Nieminen <pauli.nieminen@linux.intel.com> | 2012-05-09 23:15:22 +0300 |
---|---|---|
committer | Pauli Nieminen <pauli.nieminen@linux.intel.com> | 2012-06-05 18:33:46 +0300 |
commit | 5010a5d1a469f7963aa333cb54d06642d4cf10ce (patch) | |
tree | 7a976d16e51ccaaa9cbe9b165c07fc0477e75bcf | |
parent | 47b64c9290d54f78e5a20e378593977cd47e285f (diff) |
HACK v3: EGL_KHR_gl_texture_* supportKHR_gl_texture_image2
Now it works all except smallest levels. The smallest level samples
white only so I suspect it is some bug in my fake miptree setup. Unless
of course white while I tough rgbw should be linear filter of rgbw
values resulting to gray.
Signed-off-by: Pauli Nieminen <pauli.nieminen@linux.intel.com>
-rw-r--r-- | include/GL/internal/dri_interface.h | 13 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 84 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_texstate.c | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 17 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_blorp.cpp | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 72 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 20 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_regions.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_screen.c | 153 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_image.c | 23 |
10 files changed, 383 insertions, 23 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index e37917eda9..aacf5e2f95 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -963,6 +963,19 @@ struct __DRIimageExtensionRec { * \since 4 */ int (*write)(__DRIimage *image, const void *buf, size_t count); + + /** + * Create image from texture. + * + * \since 5 + */ + __DRIimage *(*createImageFromTexture)(__DRIcontext *context, + int target, + unsigned texture, + int level, + int depth, + void *loaderPrivate); + }; diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 4a02838383..206c960ccb 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -503,6 +503,12 @@ dri2_setup_screen(_EGLDisplay *disp) disp->Extensions.MESA_drm_image = EGL_TRUE; disp->Extensions.KHR_image_base = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; + if (dri2_dpy->image->base.version >= 5 && + dri2_dpy->image->createImageFromTexture) { + disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; + disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE; + disp->Extensions.KHR_gl_texture_3D_image = EGL_TRUE; + } } } @@ -993,6 +999,75 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, } static _EGLImage * +dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_image *dri2_img; + GLuint texture = (GLuint) (uintptr_t) buffer; + _EGLImageAttribs attrs; + GLuint depth; + GLenum gl_target; + + if (texture == 0) { + _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); + return EGL_NO_IMAGE_KHR; + } + + if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS) + return EGL_NO_IMAGE_KHR; + + switch (target) { + case EGL_GL_TEXTURE_2D_KHR: + depth = 0; + gl_target = GL_TEXTURE_2D; + break; + case EGL_GL_TEXTURE_3D_KHR: + depth = attrs.GLTextureZOffset; + gl_target = GL_TEXTURE_3D; + break; + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: + depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; + gl_target = GL_TEXTURE_CUBE_MAP; + break; + } + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); + return EGL_NO_IMAGE_KHR; + } + + if (!_eglInitImage(&dri2_img->base, disp)) { + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); + free(dri2_img); + return EGL_NO_IMAGE_KHR; + } + + dri2_img->dri_image = + dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context, + gl_target, + texture, + depth, + attrs.GLTextureLevel, + dri2_img); + + if (!dri2_img->dri_image) { + free(dri2_img); + return EGL_NO_IMAGE_KHR; + } + return &dri2_img->base; +} + +static _EGLImage * dri2_create_image_drm_name(_EGLDisplay *disp, _EGLContext *ctx, EGLint name, const _EGLImageAttribs *attrs, @@ -1120,6 +1195,15 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, (void) drv; switch (target) { + case EGL_GL_TEXTURE_2D_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: + case EGL_GL_TEXTURE_3D_KHR: + return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list); case EGL_GL_RENDERBUFFER_KHR: return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); case EGL_DRM_BUFFER_MESA: diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index fd63a69151..3c24ff5488 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -145,6 +145,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) GLint lodbias, aniso = 0; GLubyte border[4]; GLfloat maxlod; + uint32_t tile_x, tile_y; memset(state, 0, sizeof(state)); @@ -165,7 +166,10 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) drm_intel_bo_reference(intelObj->mt->region->bo); i915->state.tex_buffer[unit] = intelObj->mt->region->bo; - i915->state.tex_offset[unit] = 0; /* Always the origin of the miptree */ + i915->state.tex_offset[unit] = intel_miptree_tile_offsets(intelObj->mt, + &tile_x, &tile_y); + + assert(tile_x == 0 && tile_y == 0); format = translate_texture_format(firstImage->TexFormat, sampler->DepthMode); diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 6e745cf71a..1f81e4a3c5 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -656,6 +656,7 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit ) const GLuint surf_index = SURF_INDEX_TEXTURE(unit); uint32_t *surf; int width, height, depth; + uint32_t tile_x, tile_y; intel_miptree_get_dimensions_for_image(firstImage, &width, &height, &depth); @@ -671,7 +672,8 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit ) sampler->sRGBDecode) << BRW_SURFACE_FORMAT_SHIFT)); - surf[1] = intelObj->mt->region->bo->offset; /* reloc */ + surf[1] = (intel_miptree_tile_offsets(mt, &tile_x, &tile_y) + + intelObj->mt->region->bo->offset); /* reloc */ surf[2] = ((intelObj->_MaxLevel - tObj->BaseLevel) << BRW_SURFACE_LOD_SHIFT | (width - 1) << BRW_SURFACE_WIDTH_SHIFT | @@ -684,12 +686,21 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit ) surf[4] = 0; - surf[5] = (mt->align_h == 4) ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0; + assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0)); + /* Note that the low bits of these fields are missing, so + * there's the possibility of getting in trouble. + */ + assert(tile_x % 4 == 0); + assert(tile_y % 2 == 0); + surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT | + (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT | + (mt->align_h == 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0)); /* Emit relocation to surface contents */ drm_intel_bo_emit_reloc(brw->intel.batch.bo, brw->wm.surf_offset[surf_index] + 4, - intelObj->mt->region->bo, 0, + intelObj->mt->region->bo, + surf[1] - mt->region->bo->offset, I915_GEM_DOMAIN_SAMPLER, 0); } diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp index 601bc9bbcd..d066af28d8 100644 --- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp @@ -415,6 +415,7 @@ gen6_blorp_emit_surface_state(struct brw_context *brw, { uint32_t wm_surf_offset; uint32_t width, height; + uint32_t tile_x, tile_y; surface->get_miplevel_dims(&width, &height); if (surface->num_samples > 0) { /* TODO: seems clumsy */ width /= 2; @@ -440,7 +441,8 @@ gen6_blorp_emit_surface_state(struct brw_context *brw, format << BRW_SURFACE_FORMAT_SHIFT); /* reloc */ - surf[1] = region->bo->offset; /* No tile offsets needed */ + surf[1] = (intel_miptree_tile_offsets(surface->mt, &tile_x, &tile_y) + + region->bo->offset); /* reloc */ surf[2] = (0 << BRW_SURFACE_LOD_SHIFT | (width - 1) << BRW_SURFACE_WIDTH_SHIFT | @@ -458,8 +460,14 @@ gen6_blorp_emit_surface_state(struct brw_context *brw, surf[4] = brw_get_surface_num_multisamples(surface->num_samples); - surf[5] = (0 << BRW_SURFACE_X_OFFSET_SHIFT | - 0 << BRW_SURFACE_Y_OFFSET_SHIFT | + assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0)); + /* Note that the low bits of these fields are missing, so + * there's the possibility of getting in trouble. + */ + assert(tile_x % 4 == 0); + assert(tile_y % 2 == 0); + surf[5] = (tile_x << BRW_SURFACE_X_OFFSET_SHIFT | + tile_y << BRW_SURFACE_Y_OFFSET_SHIFT | (surface->mt->align_h == 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0)); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 7018c3732b..fef8976aa3 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -242,18 +242,24 @@ intel_miptree_create(struct intel_context *intel, return mt; } - +/** + * Create miptree for region based on offset and size + */ struct intel_mipmap_tree * -intel_miptree_create_for_region(struct intel_context *intel, +intel_miptree_create_for_offset(struct intel_context *intel, GLenum target, gl_format format, - struct intel_region *region) + struct intel_region *region, + GLuint width, + GLuint height, + GLuint offset_x, + GLuint offset_y) { struct intel_mipmap_tree *mt; mt = intel_miptree_create_internal(intel, target, format, 0, 0, - region->width, region->height, 1, + width, height, 1, true, 0 /* num_samples */, false /* msaa_is_interleaved */); if (!mt) @@ -261,10 +267,34 @@ intel_miptree_create_for_region(struct intel_context *intel, intel_region_reference(&mt->region, region); + /* Fixup tree to include correct offsets */ + mt->total_width = mt->region->width; + mt->total_height = mt->region->height; + mt->level[0].level_x = offset_x; + mt->level[0].level_y = offset_y; + mt->level[0].slice[0].x_offset = offset_x; + mt->level[0].slice[0].y_offset = offset_y; + return mt; } /** + * Convince for common case where we use whole region. + * + * See also \c intel_miptree_create_for_region_offset + */ +struct intel_mipmap_tree * +intel_miptree_create_for_region(struct intel_context *intel, + GLenum target, + gl_format format, + struct intel_region *region) +{ + return intel_miptree_create_for_offset(intel, target, format, region, + 0, 0, + 0, 0); +} + +/** * Determine whether the MSAA surface being created should use an interleaved * layout or a sliced layout, based on the chip generation and the surface * type. @@ -428,6 +458,24 @@ intel_miptree_get_dimensions_for_image(struct gl_texture_image *image, } } +uint32_t +intel_miptree_tile_offsets(struct intel_mipmap_tree *mt, + uint32_t *tile_x, + uint32_t *tile_y) +{ + struct intel_region *region = mt->region; + uint32_t mask_x, mask_y; + int fl = mt->first_level; + + intel_region_get_tile_masks(region, &mask_x, &mask_y); + + *tile_x = mt->level[fl].level_x & mask_x; + *tile_y = mt->level[fl].level_y & mask_y; + return intel_region_get_aligned_offset(region, + mt->level[fl].level_x & ~mask_x, + mt->level[fl].level_y & ~mask_y); +} + /** * Can the image be pulled into a unified mipmap tree? This mirrors * the completeness test in a lot of ways. @@ -629,6 +677,22 @@ intel_miptree_copy_teximage(struct intel_context *intel, intel_miptree_reference(&intelImage->mt, dst_mt); } +/** + * Copies all image data in from src miptree to dst miptree. + */ +void +intel_miptree_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst_mt, + struct intel_mipmap_tree *src_mt) +{ + for (GLuint level = src_mt->first_level; level < src_mt->last_level + 1; level++) { + GLuint depth = src_mt->level[level].depth; + for (GLuint slice = 0; slice < depth; slice++) { + intel_miptree_copy_slice(intel, dst_mt, src_mt, level, 0, slice); + } + } +} + bool intel_miptree_alloc_hiz(struct intel_context *intel, struct intel_mipmap_tree *mt, diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 5c57e02f03..a4473c0c48 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -267,6 +267,16 @@ intel_miptree_create_for_region(struct intel_context *intel, gl_format format, struct intel_region *region); +struct intel_mipmap_tree * +intel_miptree_create_for_offset(struct intel_context *intel, + GLenum target, + gl_format format, + struct intel_region *region, + GLuint width, + GLuint height, + GLuint offset_x, + GLuint offset_y); + /** * Create a miptree appropriate as the storage for a non-texture renderbuffer. * The miptree has the following properties: @@ -316,6 +326,11 @@ void intel_miptree_get_dimensions_for_image(struct gl_texture_image *image, int *width, int *height, int *depth); +uint32_t +intel_miptree_tile_offsets(struct intel_mipmap_tree *mt, + uint32_t *tile_x, + uint32_t *tile_y); + void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, GLuint level, GLuint x, GLuint y, @@ -330,6 +345,11 @@ intel_miptree_copy_teximage(struct intel_context *intel, struct intel_texture_image *intelImage, struct intel_mipmap_tree *dst_mt); +void +intel_miptree_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst_mt, + struct intel_mipmap_tree *src_mt); + /** * Copy the stencil data from \c mt->stencil_mt->region to \c mt->region for * the given miptree slice. diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index 2fb30eb48f..b8d4eb398f 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -148,6 +148,10 @@ struct __DRIimageRec { uint32_t dri_format; GLuint format; GLenum data_type; + GLuint width; + GLuint height; + GLuint offset_x; + GLuint offset_y; void *data; }; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 458178fe92..7a2c5b7463 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -30,11 +30,13 @@ #include "main/context.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" +#include "main/texobj.h" #include "main/hash.h" #include "main/fbobject.h" #include "main/mfeatures.h" #include "main/version.h" #include "swrast/s_renderbuffer.h" +#include "egl/main/eglcurrent.h" #include "utils.h" #include "xmlpool.h" @@ -102,6 +104,10 @@ const GLuint __driNConfigOptions = 14; #include "intel_tex.h" #include "intel_regions.h" +#ifndef I915 +#include "brw_context.h" +#endif + #include "i915_drm.h" #ifdef USE_NEW_INTERFACE @@ -175,6 +181,65 @@ static const struct __DRI2flushExtensionRec intelFlushExtension = { dri2InvalidateDrawable, }; +static void +intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *image, + struct intel_mipmap_tree **pmt, GLuint level, GLuint zoffset) +{ + struct intel_mipmap_tree *mt = *pmt; + bool has_surface_tile_offset = false; + uint32_t mask_x, mask_y; + + intel_miptree_check_level_layer(mt, level, zoffset); + + intel_region_reference(&image->region, mt->region); + image->width = mt->level[level].width; + image->height = mt->level[level].height; + image->offset_x = mt->level[level].slice[zoffset].x_offset; + image->offset_y = mt->level[level].slice[zoffset].y_offset; + + intel_region_get_tile_masks(mt->region, &mask_x, &mask_y); + +#ifndef I915 + has_surface_tile_offset = brw_context(&intel->ctx)->has_surface_tile_offset; +#endif + + if (!has_surface_tile_offset && (image->offset_x & mask_x) && + (image->offset_y & mask_y)) { + /* Driver doesn't support non-tile aligned texture offset for gen4 + * and earlier. To avoid problems with unaligned texture offset we make + * linear copy of the texture. + * + * Linear image will lose in performance but at least correct stuff + * ends to screen. + * + * If application didn't pass EGL_IMAGE_PRESERVED_KHR, EGL_TRUE but + * current internal interface assumes preserve is always set. + */ + bool texture_tiling = intel->use_texture_tiling; + intel->use_texture_tiling = false; + + struct intel_mipmap_tree *new_mt = intel_miptree_create(intel, + mt->target, mt->format, mt->first_level, mt->last_level, + mt->width0, mt->height0, mt->depth0, true, mt->num_samples, + mt->msaa_is_interleaved); + + intel->use_texture_tiling = texture_tiling; + intel_miptree_copy(intel, new_mt, mt); + intel_miptree_reference(pmt, new_mt); + image->offset_x = new_mt->level[level].slice[zoffset].x_offset; + image->offset_y = new_mt->level[level].slice[zoffset].y_offset; + } +} + +static void +intel_setup_image_from_dimensions(__DRIimage *image) +{ + image->width = image->region->width; + image->height = image->region->height; + image->offset_x = 0; + image->offset_y = 0; +} + static __DRIimage * intel_create_image_from_name(__DRIscreen *screen, int width, int height, int format, @@ -232,6 +297,8 @@ intel_create_image_from_name(__DRIscreen *screen, return NULL; } + intel_setup_image_from_dimensions(image); + return image; } @@ -246,21 +313,88 @@ intel_create_image_from_renderbuffer(__DRIcontext *context, rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer); if (!rb) { - _mesa_error(&intel->ctx, - GL_INVALID_OPERATION, "glRenderbufferExternalMESA"); + _eglError(EGL_BAD_PARAMETER, __func__); return NULL; } irb = intel_renderbuffer(rb); image = CALLOC(sizeof *image); - if (image == NULL) + if (image == NULL) { + _eglError(EGL_BAD_ALLOC, __func__); return NULL; + } image->internal_format = rb->InternalFormat; image->format = rb->Format; image->data_type = GL_UNSIGNED_BYTE; image->data = loaderPrivate; - intel_region_reference(&image->region, irb->mt->region); + intel_setup_image_from_mipmap_tree(intel, image, &irb->mt, 0, 0); + + switch (image->format) { + case MESA_FORMAT_RGB565: + image->dri_format = __DRI_IMAGE_FORMAT_RGB565; + break; + case MESA_FORMAT_XRGB8888: + image->dri_format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + case MESA_FORMAT_ARGB8888: + image->dri_format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + case MESA_FORMAT_RGBA8888_REV: + image->dri_format = __DRI_IMAGE_FORMAT_ABGR8888; + break; + } + + return image; +} + +static __DRIimage * +intel_create_image_from_texture(__DRIcontext *context, int target, + unsigned texture, int zoffset, int level, + void *loaderPrivate) +{ + __DRIimage *image; + struct intel_context *intel = context->driverPrivate; + struct gl_texture_object *obj; + struct intel_texture_object *iobj; + GLuint face = 0; + + obj = _mesa_lookup_texture(&intel->ctx, texture); + if (!obj || obj->Target != target) { + _eglError(EGL_BAD_PARAMETER, __func__); + return NULL; + } + + if (target == GL_TEXTURE_CUBE_MAP) + face = zoffset; + + _mesa_test_texobj_completeness(&intel->ctx, obj); + iobj = intel_texture_object(obj); + if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { + _eglError(EGL_BAD_PARAMETER, __func__); + return NULL; + } + + if (level < obj->BaseLevel || level > obj->_MaxLevel) { + _eglError(EGL_BAD_MATCH, __func__); + return NULL; + } + + if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) { + _eglError(EGL_BAD_MATCH, __func__); + return NULL; + } + image = CALLOC(sizeof *image); + if (image == NULL) { + _eglError(EGL_BAD_ALLOC, __func__); + return NULL; + } + + image->internal_format = obj->Image[face][level]->InternalFormat; + image->format = obj->Image[face][level]->TexFormat; + image->data_type = GL_UNSIGNED_BYTE; + image->data = loaderPrivate; + intel_setup_image_from_mipmap_tree(intel, image, &iobj->mt, level, zoffset); switch (image->format) { case MESA_FORMAT_RGB565: @@ -358,6 +492,8 @@ intel_create_image(__DRIscreen *screen, FREE(image); return NULL; } + + intel_setup_image_from_dimensions(image); return image; } @@ -402,6 +538,10 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate) image->dri_format = orig_image->dri_format; image->format = orig_image->format; image->data_type = orig_image->data_type; + image->width = orig_image->width; + image->height = orig_image->height; + image->offset_x = orig_image->offset_x; + image->offset_y = orig_image->offset_y; image->data = loaderPrivate; return image; @@ -439,7 +579,7 @@ intel_image_write(__DRIimage *image, const void *buf, size_t count) } static struct __DRIimageExtensionRec intelImageExtension = { - { __DRI_IMAGE, 4 }, + { __DRI_IMAGE, 5 }, intel_create_image_from_name, intel_create_image_from_renderbuffer, intel_destroy_image, @@ -447,7 +587,8 @@ static struct __DRIimageExtensionRec intelImageExtension = { intel_query_image, intel_dup_image, intel_validate_usage, - intel_image_write + intel_image_write, + intel_create_image_from_texture, }; static const __DRIextension *intelScreenExtensions[] = { diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index abd75c51d2..c1ed822242 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -286,7 +286,11 @@ intel_set_texture_image_region(struct gl_context *ctx, struct intel_region *region, GLenum target, GLenum internalFormat, - gl_format format) + gl_format format, + GLuint width, + GLuint height, + GLuint offset_x, + GLuint offset_y) { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intel_image = intel_texture_image(image); @@ -294,14 +298,16 @@ intel_set_texture_image_region(struct gl_context *ctx, struct intel_texture_object *intel_texobj = intel_texture_object(texobj); _mesa_init_teximage_fields(&intel->ctx, image, - region->width, region->height, 1, + width, height, 1, 0, internalFormat, format); ctx->Driver.FreeTextureImageBuffer(ctx, image); - intel_image->mt = intel_miptree_create_for_region(intel, target, + intel_image->mt = intel_miptree_create_for_offset(intel, target, image->TexFormat, - region); + region, + width, height, + offset_x, offset_y); if (intel_image->mt == NULL) return; @@ -360,7 +366,10 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, _mesa_lock_texture(&intel->ctx, texObj); texImage = _mesa_get_tex_image(ctx, texObj, target, level); intel_set_texture_image_region(ctx, texImage, rb->mt->region, target, - internalFormat, texFormat); + internalFormat, texFormat, + rb->mt->region->width, + rb->mt->region->height, + 0, 0); _mesa_unlock_texture(&intel->ctx, texObj); } @@ -391,7 +400,9 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target, return; intel_set_texture_image_region(ctx, texImage, image->region, - target, image->internal_format, image->format); + target, image->internal_format, image->format, + image->width, image->height, + image->offset_x, image->offset_y); } #endif |