*/
static void
i915_miptree_layout_cube(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
const GLuint dim = mt->width0;
GLuint face;
assert(lvlWidth == lvlHeight); /* cubemap images are square */
/* double pitch for cube layouts */
- mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, dim * 2);
mt->total_height = dim * 4;
for (level = mt->first_level; level <= mt->last_level; level++) {
static void
i915_miptree_layout_3d(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
GLuint width = mt->width0;
GLuint height = mt->height0;
GLint level;
/* Calculate the size of a single slice. */
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
/* XXX: hardware expects/requires 9 levels at minimum. */
for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) {
static void
i915_miptree_layout_2d(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
GLuint width = mt->width0;
GLuint height = mt->height0;
GLuint img_height;
GLint level;
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
mt->total_height = 0;
for (level = mt->first_level; level <= mt->last_level; level++) {
}
GLboolean
-i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
+i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
- i915_miptree_layout_cube(intel, mt);
+ i915_miptree_layout_cube(intel, mt, tiling);
break;
case GL_TEXTURE_3D:
- i915_miptree_layout_3d(intel, mt);
+ i915_miptree_layout_3d(intel, mt, tiling);
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
- i915_miptree_layout_2d(intel, mt);
+ i915_miptree_layout_2d(intel, mt, tiling);
break;
default:
_mesa_problem(NULL, "Unexpected tex target in i915_miptree_layout()");
static void
i945_miptree_layout_cube(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
const GLuint dim = mt->width0;
GLuint face;
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (dim > 32)
- mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, dim * 2);
else
- mt->pitch = intel_miptree_pitch_align (intel, mt, 14 * 8);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, 14 * 8);
if (dim >= 4)
mt->total_height = dim * 4 + 4;
static void
i945_miptree_layout_3d(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
GLuint width = mt->width0;
GLuint height = mt->height0;
GLuint pack_y_pitch;
GLuint level;
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
mt->total_height = 0;
pack_y_pitch = MAX2(mt->height0, 2);
}
GLboolean
-i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
+i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
if (mt->compressed)
- i945_miptree_layout_cube(intel, mt);
+ i945_miptree_layout_cube(intel, mt, tiling);
else
- i915_miptree_layout_cube(intel, mt);
+ i915_miptree_layout_cube(intel, mt, tiling);
break;
case GL_TEXTURE_3D:
- i945_miptree_layout_3d(intel, mt);
+ i945_miptree_layout_3d(intel, mt, tiling);
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
- i945_miptree_layout_2d(intel, mt);
+ i945_miptree_layout_2d(intel, mt, tiling);
break;
default:
_mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
GLboolean brw_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt)
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling)
{
/* XXX: these vary depending on image format: */
/* GLint align_w = 4; */
mt->pitch = ALIGN(width, align_w);
pack_y_pitch = (height + 3) / 4;
} else {
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
- pack_y_pitch = ALIGN(mt->height0, align_h);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
+ pack_y_pitch = ALIGN(mt->height0, align_h);
}
pack_x_pitch = mt->pitch;
}
default:
- i945_miptree_layout_2d(intel, mt);
+ i945_miptree_layout_2d(intel, mt, tiling);
break;
}
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
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;
*/
GLboolean is_front_buffer_rendering;
+ GLboolean use_texture_tiling;
+
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */
int perf_boxes;
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? */
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);
#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) {
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
*/
return NULL;
mt->region = intel_region_alloc(intel,
+ tiling,
mt->cpp,
mt->pitch,
mt->total_height,
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
int intel_miptree_pitch_align (struct intel_context *intel,
struct intel_mipmap_tree *mt,
+ uint32_t tiling,
int pitch)
{
#ifdef I915
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
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,
/* 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
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;
}
{
_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;
}
}
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",
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, ®ion->tiling, ®ion->bit_6_swizzle);
+ }
+
+ return region;
}
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);
#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
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)
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;
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 */
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;
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++ ) {
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);