summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c39
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h11
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c16
-rw-r--r--src/mesa/drivers/dri/intel/intel_generatemipmap.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c29
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h10
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_bitmap.c8
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_draw.c16
-rw-r--r--src/mesa/drivers/dri/intel/intel_reg.h13
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c23
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c13
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c25
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.c11
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.h4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_validate.c4
18 files changed, 201 insertions, 37 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 0db1f392c0a..23ba3b9ef67 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -111,6 +111,7 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
if (obj->Pointer)
intel_bufferobj_unmap(ctx, 0, obj);
+ _mesa_free(intel_obj->sys_buffer);
if (intel_obj->region) {
intel_bufferobj_release_region(intel, intel_obj);
}
@@ -151,7 +152,23 @@ intel_bufferobj_data(GLcontext * ctx,
dri_bo_unreference(intel_obj->buffer);
intel_obj->buffer = NULL;
}
+ _mesa_free(intel_obj->sys_buffer);
+ intel_obj->sys_buffer = NULL;
+
if (size != 0) {
+#ifdef I915
+ /* On pre-965, stick VBOs in system memory, as we're always doing swtnl
+ * with their contents anyway.
+ */
+ if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) {
+ intel_obj->sys_buffer = _mesa_malloc(size);
+ if (intel_obj->sys_buffer != NULL) {
+ if (data != NULL)
+ memcpy(intel_obj->sys_buffer, data, size);
+ return;
+ }
+ }
+#endif
intel_bufferobj_alloc_buffer(intel, intel_obj);
if (data != NULL)
@@ -181,7 +198,10 @@ intel_bufferobj_subdata(GLcontext * ctx,
if (intel_obj->region)
intel_bufferobj_cow(intel, intel_obj);
- dri_bo_subdata(intel_obj->buffer, offset, size, data);
+ if (intel_obj->sys_buffer)
+ memcpy((char *)intel_obj->sys_buffer + offset, data, size);
+ else
+ dri_bo_subdata(intel_obj->buffer, offset, size, data);
}
@@ -218,6 +238,11 @@ intel_bufferobj_map(GLcontext * ctx,
assert(intel_obj);
+ if (intel_obj->sys_buffer) {
+ obj->Pointer = intel_obj->sys_buffer;
+ return obj->Pointer;
+ }
+
if (intel_obj->region)
intel_bufferobj_cow(intel, intel_obj);
@@ -274,6 +299,18 @@ intel_bufferobj_buffer(struct intel_context *intel,
}
}
+ if (intel_obj->buffer == NULL) {
+ intel_bufferobj_alloc_buffer(intel, intel_obj);
+ intel_bufferobj_subdata(&intel->ctx,
+ GL_ARRAY_BUFFER_ARB,
+ 0,
+ intel_obj->Base.Size,
+ intel_obj->sys_buffer,
+ &intel_obj->Base);
+ _mesa_free(intel_obj->sys_buffer);
+ intel_obj->sys_buffer = NULL;
+ }
+
return intel_obj->buffer;
}
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
index 7ef723833c0..04310156319 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
@@ -42,6 +42,8 @@ struct intel_buffer_object
{
struct gl_buffer_object Base;
dri_bo *buffer; /* the low-level buffer manager's buffer handle */
+ /** System memory buffer data, if not using a BO to store the data. */
+ void *sys_buffer;
struct intel_region *region; /* Is there a zero-copy texture
associated with this (pixel)
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 49eadc75328..fa931d7f625 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -650,6 +650,13 @@ intelInitContext(struct intel_context *intel,
_mesa_init_point(ctx);
ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
+ if (IS_965(intelScreen->deviceID)) {
+ if (MAX_WIDTH > 8192)
+ ctx->Const.MaxRenderbufferSize = 8192;
+ } else {
+ if (MAX_WIDTH > 2048)
+ ctx->Const.MaxRenderbufferSize = 2048;
+ }
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext(ctx);
@@ -717,6 +724,8 @@ intelInitContext(struct intel_context *intel,
else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) {
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
}
+ intel->use_texture_tiling = driQueryOptionb(&intel->optionCache,
+ "texture_tiling");
intel->prim.primitive = ~0;
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index e931e401e93..4e45f1a91fb 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -305,6 +305,8 @@ struct intel_context
*/
GLboolean is_front_buffer_rendering;
+ GLboolean use_texture_tiling;
+
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */
int perf_boxes;
@@ -559,6 +561,9 @@ void intel_viewport(GLcontext * ctx, GLint x, GLint y,
void intel_update_renderbuffers(__DRIcontext *context,
__DRIdrawable *drawable);
+void i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region,
+ uint32_t buffer_id);
+
/*======================================================================
* Inline conversion functions.
* These are better-typed than the macros used previously:
@@ -569,4 +574,10 @@ intel_context(GLcontext * ctx)
return (struct intel_context *) ctx;
}
+static INLINE GLboolean
+is_power_of_two(uint32_t value)
+{
+ return (value & (value - 1)) == 0;
+}
+
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 52647ddf8b2..0ea413aee1d 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -217,7 +217,8 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width,
height, pitch);
- irb->region = intel_region_alloc(intel, cpp, width, height, pitch,
+ irb->region = intel_region_alloc(intel, I915_TILING_NONE,
+ cpp, width, height, pitch,
GL_TRUE);
if (!irb->region)
return GL_FALSE; /* out of memory? */
@@ -574,9 +575,10 @@ intel_render_texture(GLcontext * ctx,
ASSERT(newImage);
- if (newImage->Border != 0) {
- /* Fallback on drawing to a texture with a border, which won't have a
- * miptree.
+ intel_image = intel_texture_image(newImage);
+ if (!intel_image->mt) {
+ /* Fallback on drawing to a texture that doesn't have a miptree
+ * (has a border, width/height 0, etc.)
*/
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
_mesa_render_texture(ctx, fb, att);
@@ -607,7 +609,6 @@ intel_render_texture(GLcontext * ctx,
irb->Base.RefCount);
/* point the renderbufer's region to the texture image region */
- intel_image = intel_texture_image(newImage);
if (irb->region != intel_image->mt->region) {
if (irb->region)
intel_region_release(&irb->region);
@@ -679,6 +680,11 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
if (rb == NULL)
continue;
+ if (irb == NULL) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ continue;
+ }
+
switch (irb->texformat->MesaFormat) {
case MESA_FORMAT_ARGB8888:
case MESA_FORMAT_RGB565:
diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
index 02804b51fa8..1060fbd9e59 100644
--- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c
+++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
@@ -84,7 +84,7 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name,
/* Choose to render to the color attachment. */
_mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
- status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
+ status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
return GL_FALSE;
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index f3652720ece..0d34f28311e 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -57,7 +57,8 @@ intel_miptree_create_internal(struct intel_context *intel,
GLuint last_level,
GLuint width0,
GLuint height0,
- GLuint depth0, GLuint cpp, GLuint compress_byte)
+ GLuint depth0, GLuint cpp, GLuint compress_byte,
+ uint32_t tiling)
{
GLboolean ok;
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
@@ -81,11 +82,11 @@ intel_miptree_create_internal(struct intel_context *intel,
#ifdef I915
if (IS_945(intel->intelScreen->deviceID))
- ok = i945_miptree_layout(intel, mt);
+ ok = i945_miptree_layout(intel, mt, tiling);
else
- ok = i915_miptree_layout(intel, mt);
+ ok = i915_miptree_layout(intel, mt, tiling);
#else
- ok = brw_miptree_layout(intel, mt);
+ ok = brw_miptree_layout(intel, mt, tiling);
#endif
if (!ok) {
@@ -109,10 +110,18 @@ intel_miptree_create(struct intel_context *intel,
GLboolean expect_accelerated_upload)
{
struct intel_mipmap_tree *mt;
+ uint32_t tiling;
+
+ if (intel->use_texture_tiling && compress_byte == 0 &&
+ intel->intelScreen->kernel_exec_fencing)
+ tiling = I915_TILING_X;
+ else
+ tiling = I915_TILING_NONE;
mt = intel_miptree_create_internal(intel, target, internal_format,
first_level, last_level, width0,
- height0, depth0, cpp, compress_byte);
+ height0, depth0, cpp, compress_byte,
+ tiling);
/*
* pitch == 0 || height == 0 indicates the null texture
*/
@@ -120,6 +129,7 @@ intel_miptree_create(struct intel_context *intel,
return NULL;
mt->region = intel_region_alloc(intel,
+ tiling,
mt->cpp,
mt->pitch,
mt->total_height,
@@ -149,7 +159,8 @@ intel_miptree_create_for_region(struct intel_context *intel,
mt = intel_miptree_create_internal(intel, target, internal_format,
first_level, last_level,
region->width, region->height, 1,
- region->cpp, compress_byte);
+ region->cpp, compress_byte,
+ I915_TILING_NONE);
if (!mt)
return mt;
#if 0
@@ -187,6 +198,7 @@ intel_miptree_create_for_region(struct intel_context *intel,
int intel_miptree_pitch_align (struct intel_context *intel,
struct intel_mipmap_tree *mt,
+ uint32_t tiling,
int pitch)
{
#ifdef I915
@@ -207,6 +219,11 @@ int intel_miptree_pitch_align (struct intel_context *intel,
pitch_align = 4;
}
+ if (tiling == I915_TILING_X)
+ pitch_align = 512;
+ else if (tiling == I915_TILING_Y)
+ pitch_align = 128;
+
pitch = ALIGN(pitch * mt->cpp, pitch_align);
#ifdef I915
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 4060b9df78f..3af9966827f 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -148,6 +148,7 @@ intel_miptree_create_for_region(struct intel_context *intel,
int intel_miptree_pitch_align (struct intel_context *intel,
struct intel_mipmap_tree *mt,
+ uint32_t tiling,
int pitch);
void intel_miptree_reference(struct intel_mipmap_tree **dst,
@@ -218,10 +219,13 @@ void intel_miptree_image_copy(struct intel_context *intel,
/* i915_mipmap_tree.c:
*/
GLboolean i915_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt);
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
GLboolean i945_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt);
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
GLboolean brw_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt);
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
index b20840b9a06..80d3239189c 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
@@ -400,6 +400,14 @@ intel_texture_bitmap(GLcontext * ctx,
return GL_FALSE;
}
+ if (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ (!is_power_of_two(width) || !is_power_of_two(height))) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr,
+ "glBitmap() fallback: NPOT texture\n");
+ return GL_FALSE;
+ }
+
/* Check that we can load in a texture this big. */
if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) ||
height > (1 << (ctx->Const.MaxTextureLevels - 1))) {
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
index abcdcd5724c..7cda6adb32b 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
@@ -119,6 +119,14 @@ intel_texture_drawpixels(GLcontext * ctx,
return GL_FALSE;
}
+ if (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ (!is_power_of_two(width) || !is_power_of_two(height))) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr,
+ "glDrawPixels() fallback: NPOT texture\n");
+ return GL_FALSE;
+ }
+
_mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
GL_CURRENT_BIT);
_mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
@@ -262,6 +270,14 @@ intel_stencil_drawpixels(GLcontext * ctx,
return GL_FALSE;
}
+ if (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ (!is_power_of_two(width) || !is_power_of_two(height))) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr,
+ "glDrawPixels(GL_STENCIL_INDEX) fallback: NPOT texture\n");
+ return GL_FALSE;
+ }
+
_mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
diff --git a/src/mesa/drivers/dri/intel/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h
index 57ac8f0cc14..d19f1bae34c 100644
--- a/src/mesa/drivers/dri/intel/intel_reg.h
+++ b/src/mesa/drivers/dri/intel/intel_reg.h
@@ -189,6 +189,19 @@
#define S7_DEPTH_OFFSET_CONST_MASK ~0
+/* p143 */
+#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
+/* Dword 1 */
+#define BUF_3D_ID_COLOR_BACK (0x3<<24)
+#define BUF_3D_ID_DEPTH (0x7<<24)
+#define BUF_3D_USE_FENCE (1<<23)
+#define BUF_3D_TILED_SURFACE (1<<22)
+#define BUF_3D_TILE_WALK_X 0
+#define BUF_3D_TILE_WALK_Y (1<<21)
+#define BUF_3D_PITCH(x) (((x)/4)<<2)
+/* Dword 2 */
+#define BUF_3D_ADDR(x) ((x) & ~0x3)
+
/* Primitive dispatch on 830-945 */
#define _3DPRIMITIVE (CMD_3D | (0x1f << 24))
#define PRIM_INDIRECT (1<<23)
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 534e75efe1f..fd9bf7b1741 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -116,7 +116,10 @@ intel_region_map(struct intel_context *intel, struct intel_region *region)
if (region->pbo)
intel_region_cow(intel, region);
- dri_bo_map(region->buffer, GL_TRUE);
+ if (intel->intelScreen->kernel_exec_fencing)
+ drm_intel_gem_bo_map_gtt(region->buffer);
+ else
+ dri_bo_map(region->buffer, GL_TRUE);
region->map = region->buffer->virtual;
}
@@ -128,7 +131,10 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region)
{
_DBG("%s %p\n", __FUNCTION__, region);
if (!--region->map_refcount) {
- dri_bo_unmap(region->buffer);
+ if (intel->intelScreen->kernel_exec_fencing)
+ drm_intel_gem_bo_map_gtt(region->buffer);
+ else
+ dri_bo_unmap(region->buffer);
region->map = NULL;
}
}
@@ -164,10 +170,12 @@ intel_region_alloc_internal(struct intel_context *intel,
struct intel_region *
intel_region_alloc(struct intel_context *intel,
+ uint32_t tiling,
GLuint cpp, GLuint width, GLuint height, GLuint pitch,
GLboolean expect_accelerated_upload)
{
dri_bo *buffer;
+ struct intel_region *region;
if (expect_accelerated_upload) {
buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
@@ -177,7 +185,16 @@ intel_region_alloc(struct intel_context *intel,
pitch * cpp * height, 64);
}
- return intel_region_alloc_internal(intel, cpp, width, height, pitch, buffer);
+ region = intel_region_alloc_internal(intel, cpp, width, height,
+ pitch, buffer);
+
+ if (tiling != I915_TILING_NONE) {
+ assert(((pitch * cpp) & 511) == 0);
+ drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp);
+ drm_intel_bo_get_tiling(buffer, &region->tiling, &region->bit_6_swizzle);
+ }
+
+ return region;
}
struct intel_region *
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 45e2bf4e77a..bd3c8e7325b 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -73,7 +73,8 @@ struct intel_region
* copied by calling intel_reference_region().
*/
struct intel_region *intel_region_alloc(struct intel_context *intel,
- GLuint cpp, GLuint width,
+ uint32_t tiling,
+ GLuint cpp, GLuint width,
GLuint height, GLuint pitch,
GLboolean expect_accelerated_upload);
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 27288231426..6521b4ef313 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -49,6 +49,10 @@
#include "i915_drm.h"
#include "i830_dri.h"
+#define DRI_CONF_TEXTURE_TILING(def) \
+ DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \
+ DRI_CONF_DESC(en, "Enable texture tiling") \
+ DRI_CONF_OPT_END \
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
@@ -64,6 +68,13 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
DRI_CONF_DESC_END
DRI_CONF_OPT_END
+
+#ifdef I915
+ DRI_CONF_TEXTURE_TILING(false)
+#else
+ DRI_CONF_TEXTURE_TILING(true)
+#endif
+
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
@@ -76,7 +87,7 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_SECTION_END
DRI_CONF_END;
-const GLuint __driNConfigOptions = 8;
+const GLuint __driNConfigOptions = 9;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 7c2b26ef1d4..673b8fa6a11 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -118,8 +118,12 @@ do_copy_texsubimage(struct intel_context *intel,
dstx += x - orig_x;
dsty += y - orig_y;
- /* image_offset may be non-page-aligned, but that's illegal for tiling. */
- assert(intelImage->mt->region->tiling == I915_TILING_NONE);
+ /* Can't blit to tiled buffers with non-tile-aligned offset. */
+ if (intelImage->mt->region->tiling != I915_TILING_NONE &&
+ (image_offset & 4095) != 0) {
+ UNLOCK_HARDWARE(intel);
+ return GL_FALSE;
+ }
if (ctx->ReadBuffer->Name == 0) {
/* reading from a window, adjust x, y */
@@ -231,6 +235,14 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
if (border)
goto fail;
+ /* Setup or redefine the texture object, mipmap tree and texture
+ * image. Don't populate yet.
+ */
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border,
+ GL_RGBA, CHAN_TYPE, NULL,
+ &ctx->DefaultPacking, texObj, texImage);
+
srcx = x;
srcy = y;
dstx = 0;
@@ -241,15 +253,6 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
&width, &height))
return;
- /* Setup or redefine the texture object, mipmap tree and texture
- * image. Don't populate yet.
- */
- ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
- width, height, border,
- GL_RGBA, CHAN_TYPE, NULL,
- &ctx->DefaultPacking, texObj, texImage);
-
-
if (!do_copy_texsubimage(intel_context(ctx), target,
intel_texture_image(texImage),
internalFormat, 0, 0, x, y, width, height))
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index e6f9a417790..b8be7ef41a2 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -52,7 +52,9 @@ GLuint intel_compressed_alignment(GLenum internalFormat)
return alignment;
}
-void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt )
+void i945_miptree_layout_2d( struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling )
{
GLint align_h = 2, align_w = 4;
GLuint level;
@@ -86,13 +88,18 @@ void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tr
if (mip1_width > mt->pitch) {
mt->pitch = mip1_width;
+
+ if (tiling == I915_TILING_X)
+ mt->pitch = ALIGN(mt->pitch * mt->cpp, 512) / mt->cpp;
+ if (tiling == I915_TILING_Y)
+ mt->pitch = ALIGN(mt->pitch * mt->cpp, 128) / mt->cpp;
}
}
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->pitch);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->pitch);
mt->total_height = 0;
for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h
index dbc90e6f9b7..7bc25b6bcb1 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h
@@ -38,5 +38,7 @@ static GLuint minify( GLuint d )
return MAX2(1, d>>1);
}
-extern void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt );
+extern void i945_miptree_layout_2d(struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
extern GLuint intel_compressed_alignment(GLenum);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index 05a375e1f3b..b5cb7597d16 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -241,7 +241,7 @@ intel_tex_map_level_images(struct intel_context *intel,
struct intel_texture_image *intelImage =
intel_texture_image(intelObj->base.Image[face][level]);
- if (intelImage->mt) {
+ if (intelImage && intelImage->mt) {
intelImage->base.Data =
intel_miptree_image_map(intel,
intelImage->mt,
@@ -268,7 +268,7 @@ intel_tex_unmap_level_images(struct intel_context *intel,
struct intel_texture_image *intelImage =
intel_texture_image(intelObj->base.Image[face][level]);
- if (intelImage->mt) {
+ if (intelImage && intelImage->mt) {
intel_miptree_image_unmap(intel, intelImage->mt);
intelImage->base.Data = NULL;
}