summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i915
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/i915')
-rw-r--r--src/gallium/drivers/i915/TODO25
-rw-r--r--src/gallium/drivers/i915/i915_batch.h5
-rw-r--r--src/gallium/drivers/i915/i915_batchbuffer.h35
-rw-r--r--src/gallium/drivers/i915/i915_blit.c6
-rw-r--r--src/gallium/drivers/i915/i915_context.h3
-rw-r--r--src/gallium/drivers/i915/i915_debug.c2
-rw-r--r--src/gallium/drivers/i915/i915_debug.h1
-rw-r--r--src/gallium/drivers/i915/i915_prim_vbuf.c15
-rw-r--r--src/gallium/drivers/i915/i915_reg.h3
-rw-r--r--src/gallium/drivers/i915/i915_resource.h10
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c106
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c69
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c20
-rw-r--r--src/gallium/drivers/i915/i915_surface.c9
-rw-r--r--src/gallium/drivers/i915/i915_winsys.h29
15 files changed, 237 insertions, 101 deletions
diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO
new file mode 100644
index 00000000000..94c428bebf8
--- /dev/null
+++ b/src/gallium/drivers/i915/TODO
@@ -0,0 +1,25 @@
+Random list of problems with i915g:
+
+- Dies with BadDrawable on GLXFBconfig changes/destruction. Makes piglit totally
+ unusable :( Upgrading xserver helped here, it doesn't crash anymore. Still
+ broken, it doesn't update the viewport/get new buffers.
+
+- Tends to hang the chip after a few minutes of openarena. Looks tiling related,
+ at the last frame rendered has tiling corruption over the complete frame.
+
+- Kills the chip in 3D_PRIMITIVE LINELIST with mesa-demos/fbotexture in
+ wireframe mode.
+
+- Tiling is funny: If unlucky, it renders/samples all black. No clue yet what's
+ going on. Seems to depend on tiny details like whethever the sampler
+ relocation is fenced/unfenced (broken _with_ fenced reloc using tiling bits!).
+
+- Y-tiling is even more fun. i915c doesn't use it, maybe there's a reason?
+ Texture sampling from Y-tiled buffers seems to work, though (save above
+ problems).
+
+- Need to validate buffers before usage. Currently do_exec on the batchbuffer
+ can fail with -ENOSPC.
+
+Other bugs can be found here:
+https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g
diff --git a/src/gallium/drivers/i915/i915_batch.h b/src/gallium/drivers/i915/i915_batch.h
index c411b84ccd4..6e93da76209 100644
--- a/src/gallium/drivers/i915/i915_batch.h
+++ b/src/gallium/drivers/i915/i915_batch.h
@@ -38,7 +38,10 @@
i915_winsys_batchbuffer_dword(i915->batch, dword)
#define OUT_RELOC(buf, usage, offset) \
- i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset)
+ i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, false)
+
+#define OUT_RELOC_FENCED(buf, usage, offset) \
+ i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, true)
#define FLUSH_BATCH(fence) \
i915_flush(i915, fence)
diff --git a/src/gallium/drivers/i915/i915_batchbuffer.h b/src/gallium/drivers/i915/i915_batchbuffer.h
index c1cd314e7b8..d92b2ccb31e 100644
--- a/src/gallium/drivers/i915/i915_batchbuffer.h
+++ b/src/gallium/drivers/i915/i915_batchbuffer.h
@@ -29,42 +29,47 @@
#define I915_BATCHBUFFER_H
#include "i915_winsys.h"
+#include "util/u_debug.h"
struct i915_context;
+static INLINE size_t
+i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
+{
+ return batch->size - (batch->ptr - batch->map);
+}
+
static INLINE boolean
i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch,
size_t dwords,
size_t relocs)
{
- return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
+ return dwords * 4 <= i915_winsys_batchbuffer_space(batch) &&
relocs <= (batch->max_relocs - batch->relocs);
}
-static INLINE size_t
-i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
+static INLINE void
+i915_winsys_batchbuffer_dword_unchecked(struct i915_winsys_batchbuffer *batch,
+ unsigned dword)
{
- return batch->size - (batch->ptr - batch->map);
+ *(unsigned *)batch->ptr = dword;
+ batch->ptr += 4;
}
static INLINE void
i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch,
unsigned dword)
{
- if (i915_winsys_batchbuffer_space(batch) < 4)
- return;
-
- *(unsigned *)batch->ptr = dword;
- batch->ptr += 4;
+ assert (i915_winsys_batchbuffer_space(batch) >= 4);
+ i915_winsys_batchbuffer_dword_unchecked(batch, dword);
}
static INLINE void
i915_winsys_batchbuffer_write(struct i915_winsys_batchbuffer *batch,
- void *data,
- size_t size)
+ void *data,
+ size_t size)
{
- if (i915_winsys_batchbuffer_space(batch) < size)
- return;
+ assert (i915_winsys_batchbuffer_space(batch) >= size);
memcpy(data, batch->ptr, size);
batch->ptr += size;
@@ -74,9 +79,9 @@ static INLINE int
i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch,
struct i915_winsys_buffer *buffer,
enum i915_winsys_buffer_usage usage,
- size_t offset)
+ size_t offset, bool fenced)
{
- return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
+ return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset, fenced);
}
#endif
diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c
index cdf20c0055a..97c25665156 100644
--- a/src/gallium/drivers/i915/i915_blit.c
+++ b/src/gallium/drivers/i915/i915_blit.c
@@ -74,7 +74,7 @@ i915_fill_blit(struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((y << 16) | x);
OUT_BATCH(((y + h) << 16) | (x + w));
- OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
+ OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
OUT_BATCH(color);
}
@@ -138,8 +138,8 @@ i915_copy_blit(struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((dst_y << 16) | dst_x);
OUT_BATCH((dst_y2 << 16) | dst_x2);
- OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
+ OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
OUT_BATCH((src_y << 16) | src_x);
OUT_BATCH(((int) src_pitch & 0xffff));
- OUT_RELOC(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
+ OUT_RELOC_FENCED(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
}
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 3ae61d0ea70..7103a1b8c16 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -193,8 +193,7 @@ struct i915_velems_state {
};
-struct i915_context
-{
+struct i915_context {
struct pipe_context base;
struct i915_winsys *iws;
diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c
index 57d3390dea3..d7150c99c4e 100644
--- a/src/gallium/drivers/i915/i915_debug.c
+++ b/src/gallium/drivers/i915/i915_debug.c
@@ -46,10 +46,12 @@ static const struct debug_named_value debug_options[] = {
};
unsigned i915_debug = 0;
+boolean i915_tiling = TRUE;
void i915_debug_init(struct i915_screen *screen)
{
i915_debug = debug_get_flags_option("I915_DEBUG", debug_options, 0);
+ i915_tiling = !debug_get_bool_option("I915_NO_TILING", FALSE);
}
diff --git a/src/gallium/drivers/i915/i915_debug.h b/src/gallium/drivers/i915/i915_debug.h
index fa60799d0c5..11af7662f0a 100644
--- a/src/gallium/drivers/i915/i915_debug.h
+++ b/src/gallium/drivers/i915/i915_debug.h
@@ -46,6 +46,7 @@ struct i915_winsys_batchbuffer;
#define DBG_CONSTANTS 0x20
extern unsigned i915_debug;
+extern boolean i915_tiling;
#ifdef DEBUG
static INLINE boolean
diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c
index bd046bd9058..baebbc7bae3 100644
--- a/src/gallium/drivers/i915/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915/i915_prim_vbuf.c
@@ -172,6 +172,7 @@ i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
*
* Side effects:
* Updates hw_offset, sw_offset, index and allocates a new buffer.
+ * Will set i915->vbo to null on buffer allocation.
*/
static void
i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
@@ -179,8 +180,16 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
struct i915_context *i915 = i915_render->i915;
struct i915_winsys *iws = i915->iws;
- if (i915_render->vbo)
+ if (i915_render->vbo) {
iws->buffer_destroy(iws, i915_render->vbo);
+ /*
+ * XXX If buffers where referenced then this should be done in
+ * update_vbo_state but since they arn't and malloc likes to reuse
+ * memory we need to set it to null
+ */
+ i915->vbo = NULL;
+ i915_render->vbo = NULL;
+ }
i915->vbo_flushed = 0;
@@ -198,7 +207,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
#endif
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size,
- 64, I915_NEW_VERTEX);
+ I915_NEW_VERTEX);
}
/**
@@ -726,7 +735,7 @@ i915_vbuf_render_create(struct i915_context *i915)
i915_render->pool_fifo = u_fifo_create(6);
for (i = 0; i < 6; i++)
u_fifo_add(i915_render->pool_fifo,
- iws->buffer_create(iws, i915_render->pool_buffer_size, 64,
+ iws->buffer_create(iws, i915_render->pool_buffer_size,
I915_NEW_VERTEX));
#else
(void)i;
diff --git a/src/gallium/drivers/i915/i915_reg.h b/src/gallium/drivers/i915/i915_reg.h
index cc28891e4ac..5e4e80ddf6b 100644
--- a/src/gallium/drivers/i915/i915_reg.h
+++ b/src/gallium/drivers/i915/i915_reg.h
@@ -753,7 +753,7 @@
#define MT_COMPRESS_DXT1_RGB (4<<3)
#define MS3_USE_FENCE_REGS (1<<2)
#define MS3_TILED_SURFACE (1<<1)
-#define MS3_TILE_WALK (1<<0)
+#define MS3_TILE_WALK_Y (1<<0)
#define MS4_PITCH_SHIFT 21
#define MS4_CUBE_FACE_ENA_NEGX (1<<20)
@@ -851,6 +851,7 @@
#define MI_FLUSH ((0<<29)|(4<<23))
#define FLUSH_MAP_CACHE (1<<0)
#define INHIBIT_FLUSH_RENDER_CACHE (1<<2)
+#define MI_NOOP 0
#define CMD_3D (0x3<<29)
diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h
index 753bd266b12..86620e6a123 100644
--- a/src/gallium/drivers/i915/i915_resource.h
+++ b/src/gallium/drivers/i915/i915_resource.h
@@ -49,6 +49,10 @@ struct i915_buffer {
#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+struct offset_pair {
+ unsigned short nblocksx;
+ unsigned short nblocksy;
+};
struct i915_texture {
struct u_resource b;
@@ -63,14 +67,18 @@ struct i915_texture {
/* Explicitly store the offset of each image for each cube face or
* depth value.
+ *
+ * Array [depth] off offsets.
*/
- unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; /**< array [depth] of offsets */
+ struct offset_pair *image_offset[I915_MAX_TEXTURE_2D_LEVELS];
/* The data is held here:
*/
struct i915_winsys_buffer *buffer;
};
+unsigned i915_texture_offset(struct i915_texture *tex,
+ unsigned level, unsigned layer);
void i915_init_screen_resource_functions(struct i915_screen *is);
void i915_init_resource_functions(struct i915_context *i915);
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index 67356abe208..f19106f3414 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -106,6 +106,23 @@ get_pot_stride(enum pipe_format format, unsigned width)
return util_next_power_of_two(util_format_get_stride(format, width));
}
+static INLINE const char*
+get_tiling_string(enum i915_winsys_buffer_tile tile)
+{
+ switch(tile) {
+ case I915_TILE_NONE:
+ return "none";
+ case I915_TILE_X:
+ return "x";
+ case I915_TILE_Y:
+ return "y";
+ default:
+ assert(FALSE);
+ return "?";
+ }
+}
+
+
/*
* More advanced helper funcs
*/
@@ -120,28 +137,56 @@ i915_texture_set_level_info(struct i915_texture *tex,
assert(!tex->image_offset[level]);
tex->nr_images[level] = nr_images;
- tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
- tex->image_offset[level][0] = 0;
+ tex->image_offset[level] = MALLOC(nr_images * sizeof(struct offset_pair));
+ tex->image_offset[level][0].nblocksx = 0;
+ tex->image_offset[level][0].nblocksy = 0;
+}
+
+INLINE unsigned i915_texture_offset(struct i915_texture *tex,
+ unsigned level, unsigned layer)
+{
+ unsigned x, y;
+ x = tex->image_offset[level][layer].nblocksx
+ * util_format_get_blocksize(tex->b.b.format);
+ y = tex->image_offset[level][layer].nblocksy;
+
+ return y * tex->stride + x;
}
static void
i915_texture_set_image_offset(struct i915_texture *tex,
unsigned level, unsigned img,
- unsigned x, unsigned y)
+ unsigned nblocksx, unsigned nblocksy)
{
/* for the first image and level make sure offset is zero */
- assert(!(img == 0 && level == 0) || (x == 0 && y == 0));
+ assert(!(img == 0 && level == 0) || (nblocksx == 0 && nblocksy == 0));
assert(img < tex->nr_images[level]);
- tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->b.b.format);
+ tex->image_offset[level][img].nblocksx = nblocksx;
+ tex->image_offset[level][img].nblocksy = nblocksy;
#if DEBUG_TEXTURES
- debug_printf("%s: %p level %u, img %u (%u, %u) %p\n", __FUNCTION__,
- tex, level, img, x, y,
- (void*)(uintptr_t)tex->image_offset[level][img]);
+ debug_printf("%s: %p level %u, img %u (%u, %u)\n", __FUNCTION__,
+ tex, level, img, x, y);
#endif
}
+static enum i915_winsys_buffer_tile
+i915_texture_tiling(struct pipe_resource *pt)
+{
+ if (!i915_tiling)
+ return I915_TILE_NONE;
+
+ if (pt->target == PIPE_TEXTURE_1D)
+ return I915_TILE_NONE;
+
+ if (util_format_is_s3tc(pt->format))
+ /* XXX X-tiling might make sense */
+ return I915_TILE_NONE;
+
+ return I915_TILE_X;
+}
+
/*
* Shared layout functions
@@ -163,9 +208,10 @@ i9x5_scanout_layout(struct i915_texture *tex)
i915_texture_set_image_offset(tex, 0, 0, 0, 0);
if (pt->width0 >= 240) {
- tex->stride = get_pot_stride(pt->format, pt->width0);
+ tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64);
tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
tex->tiling = I915_TILE_X;
+ /* special case for cursors */
} else if (pt->width0 == 64 && pt->height0 == 64) {
tex->stride = get_pot_stride(pt->format, pt->width0);
tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
@@ -200,7 +246,7 @@ i9x5_display_target_layout(struct i915_texture *tex)
i915_texture_set_level_info(tex, 0, 1);
i915_texture_set_image_offset(tex, 0, 0, 0, 0);
- tex->stride = get_pot_stride(pt->format, pt->width0);
+ tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64);
tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
tex->tiling = I915_TILE_X;
@@ -357,6 +403,8 @@ i915_texture_layout(struct i915_texture * tex)
{
struct pipe_resource *pt = &tex->b.b;
+ tex->tiling = i915_texture_tiling(pt);
+
switch (pt->target) {
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
@@ -603,6 +651,8 @@ i945_texture_layout(struct i915_texture * tex)
{
struct pipe_resource *pt = &tex->b.b;
+ tex->tiling = i915_texture_tiling(pt);
+
switch (pt->target) {
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
@@ -687,7 +737,6 @@ i915_texture_get_transfer(struct pipe_context *context,
return transfer;
}
-
static void *
i915_texture_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
@@ -703,7 +752,7 @@ i915_texture_transfer_map(struct pipe_context *pipe,
if (resource->target != PIPE_TEXTURE_3D &&
resource->target != PIPE_TEXTURE_CUBE)
assert(box->z == 0);
- offset = tex->image_offset[transfer->level][box->z];
+ offset = i915_texture_offset(tex, transfer->level, box->z);
map = iws->buffer_map(iws, tex->buffer,
(transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
@@ -749,7 +798,6 @@ i915_texture_create(struct pipe_screen *screen,
struct i915_screen *is = i915_screen(screen);
struct i915_winsys *iws = is->iws;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
- size_t tex_size;
unsigned buf_usage = 0;
if (!tex)
@@ -768,8 +816,6 @@ i915_texture_create(struct pipe_screen *screen,
goto fail;
}
- tex_size = tex->stride * tex->total_nblocksy;
-
/* for scanouts and cursors, cursors arn't scanouts */
/* XXX: use a custom flag for cursors, don't rely on magically
@@ -780,27 +826,15 @@ i915_texture_create(struct pipe_screen *screen,
else
buf_usage = I915_NEW_TEXTURE;
- tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
+ tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
+ &tex->tiling, buf_usage);
if (!tex->buffer)
goto fail;
- /* setup any hw fences */
- if (tex->tiling) {
- iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->tiling);
- }
-
-
-#if 0
- void *ptr = ws->buffer_map(ws, tex->buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- memset(ptr, 0x80, tex_size);
- ws->buffer_unmap(ws, tex->buffer);
-#endif
-
- I915_DBG(DBG_TEXTURE, "%s: %p size %u, stride %u, blocks (%u, %u)\n", __func__,
- tex, (unsigned int)tex_size, tex->stride,
+ I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u) tiling %s\n", __func__,
+ tex, tex->stride,
tex->stride / util_format_get_blocksize(tex->b.b.format),
- tex->total_nblocksy);
+ tex->total_nblocksy, get_tiling_string(tex->tiling));
return &tex->b.b;
@@ -819,10 +853,11 @@ i915_texture_from_handle(struct pipe_screen * screen,
struct i915_winsys *iws = is->iws;
struct i915_winsys_buffer *buffer;
unsigned stride;
+ enum i915_winsys_buffer_tile tiling;
assert(screen);
- buffer = iws->buffer_from_handle(iws, whandle, &stride);
+ buffer = iws->buffer_from_handle(iws, whandle, &tiling, &stride);
/* Only supports one type */
if ((template->target != PIPE_TEXTURE_2D &&
@@ -842,6 +877,7 @@ i915_texture_from_handle(struct pipe_screen * screen,
tex->b.b.screen = screen;
tex->stride = stride;
+ tex->tiling = tiling;
tex->total_nblocksy = align_nblocksy(tex->b.b.format, tex->b.b.height0, 8);
i915_texture_set_level_info(tex, 0, 1);
@@ -849,10 +885,10 @@ i915_texture_from_handle(struct pipe_screen * screen,
tex->buffer = buffer;
- I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%ux%u)\n", __func__,
+ I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u) tiling %s\n", __func__,
tex, tex->stride,
tex->stride / util_format_get_blocksize(tex->b.b.format),
- tex->total_nblocksy);
+ tex->total_nblocksy, get_tiling_string(tex->tiling));
return &tex->b.b;
}
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 9292fa00b43..c48d53ffbb2 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -86,6 +86,22 @@ framebuffer_size(const struct pipe_framebuffer_state *fb,
}
}
+static inline uint32_t
+buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling)
+{
+ uint32_t tiling_bits = 0;
+
+ switch (tiling) {
+ case I915_TILE_Y:
+ tiling_bits |= BUF_3D_TILE_WALK_Y;
+ case I915_TILE_X:
+ tiling_bits |= BUF_3D_TILED_SURFACE;
+ case I915_TILE_NONE:
+ break;
+ }
+
+ return tiling_bits;
+}
/* Push the state into the sarea and/or texture memory.
*/
@@ -220,44 +236,39 @@ i915_emit_hardware_state(struct i915_context *i915 )
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
if (cbuf_surface) {
- unsigned ctile = BUF_3D_USE_FENCE;
struct i915_texture *tex = i915_texture(cbuf_surface->texture);
- unsigned offset;
assert(tex);
- offset = tex->image_offset[cbuf_surface->u.tex.level][cbuf_surface->u.tex.first_layer];
-
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
- ctile);
+ buf_3d_tiling_bits(tex->tiling));
OUT_RELOC(tex->buffer,
I915_USAGE_RENDER,
- offset);
+ 0);
}
/* What happens if no zbuf??
*/
if (depth_surface) {
- unsigned ztile = BUF_3D_USE_FENCE;
struct i915_texture *tex = i915_texture(depth_surface->texture);
- unsigned offset;
+ unsigned offset = i915_texture_offset(tex, depth_surface->u.tex.level,
+ depth_surface->u.tex.first_layer);
assert(tex);
-
- offset = tex->image_offset[depth_surface->u.tex.level][depth_surface->u.tex.first_layer];
+ assert(offset == 0);
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
assert(tex);
OUT_BATCH(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
- ztile);
+ buf_3d_tiling_bits(tex->tiling));
OUT_RELOC(tex->buffer,
I915_USAGE_RENDER,
- offset);
+ 0);
}
{
@@ -299,12 +310,11 @@ i915_emit_hardware_state(struct i915_context *i915 )
if (enabled & (1 << unit)) {
struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture);
struct i915_winsys_buffer *buf = texture->buffer;
- uint offset = 0;
assert(buf);
count++;
- OUT_RELOC(buf, I915_USAGE_SAMPLER, offset);
+ OUT_RELOC(buf, I915_USAGE_SAMPLER, 0);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
}
@@ -397,18 +407,33 @@ i915_emit_hardware_state(struct i915_context *i915 )
#if 01
/* drawing surface size */
/* 6 dwords, 0 relocs */
+ if (i915->hardware_dirty & I915_HW_STATIC)
{
uint w, h;
- boolean k = framebuffer_size(&i915->framebuffer, &w, &h);
- (void)k;
- assert(k);
+ struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+ struct i915_texture *tex = i915_texture(cbuf_surface->texture);
+ unsigned x, y;
+ int layer;
+ uint32_t draw_offset;
+ boolean ret;
+ ret = framebuffer_size(&i915->framebuffer, &w, &h);
+ assert(ret);
+
+ layer = cbuf_surface->u.tex.first_layer;
+
+ x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx;
+ y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy;
+
+ draw_offset = x | (y << 16);
+
+ /* XXX flush only required when the draw_offset changes! */
+ OUT_BATCH(MI_FLUSH | INHIBIT_FLUSH_RENDER_CACHE);
OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(((w - 1) & 0xffff) | ((h - 1) << 16));
- OUT_BATCH(0);
- OUT_BATCH(0);
+ OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS);
+ OUT_BATCH(draw_offset);
+ OUT_BATCH((w - 1 + x) | ((h - 1 + y) << 16));
+ OUT_BATCH(draw_offset);
}
#endif
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index 9771274ca11..916cb767536 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -243,6 +243,23 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
}
}
+static inline uint32_t
+ms3_tiling_bits(enum i915_winsys_buffer_tile tiling)
+{
+ uint32_t tiling_bits = 0;
+
+ switch (tiling) {
+ case I915_TILE_Y:
+ tiling_bits |= MS3_TILE_WALK_Y;
+ case I915_TILE_X:
+ tiling_bits |= MS3_TILED_SURFACE;
+ case I915_TILE_NONE:
+ break;
+ }
+
+ return tiling_bits;
+}
+
static void update_map(struct i915_context *i915,
uint unit,
const struct i915_texture *tex,
@@ -254,7 +271,6 @@ static void update_map(struct i915_context *i915,
const uint width = pt->width0, height = pt->height0, depth = pt->depth0;
const uint num_levels = pt->last_level;
unsigned max_lod = num_levels * 4;
- unsigned tiled = MS3_USE_FENCE_REGS;
assert(tex);
assert(width);
@@ -272,7 +288,7 @@ static void update_map(struct i915_context *i915,
(((height - 1) << MS3_HEIGHT_SHIFT)
| ((width - 1) << MS3_WIDTH_SHIFT)
| format
- | tiled);
+ | ms3_tiling_bits(tex->tiling));
/*
* XXX When min_filter != mag_filter and there's just one mipmap level,
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index 4ac1f90ef95..becc6e93c2d 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -59,13 +59,12 @@ i915_surface_copy(struct pipe_context *pipe,
if (dst->target != PIPE_TEXTURE_CUBE &&
dst->target != PIPE_TEXTURE_3D)
assert(dstz == 0);
- dst_offset = dst_tex->image_offset[dst_level][dstz];
+ dst_offset = i915_texture_offset(dst_tex, dst_level, dstz);
if (src->target != PIPE_TEXTURE_CUBE &&
src->target != PIPE_TEXTURE_3D)
assert(src_box->z == 0);
- src_offset = src_tex->image_offset[src_level][src_box->z];
-
+ src_offset = i915_texture_offset(src_tex, src_level, src_box->z);
assert( dst != src );
assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) );
@@ -93,7 +92,7 @@ i915_clear_render_target(struct pipe_context *pipe,
struct i915_texture *tex = i915_texture(dst->texture);
struct pipe_resource *pt = &tex->b.b;
union util_color uc;
- unsigned offset = tex->image_offset[dst->u.tex.level][dst->u.tex.first_layer];
+ unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
assert(util_format_get_blockwidth(pt->format) == 1);
assert(util_format_get_blockheight(pt->format) == 1);
@@ -122,7 +121,7 @@ i915_clear_depth_stencil(struct pipe_context *pipe,
struct pipe_resource *pt = &tex->b.b;
unsigned packedds;
unsigned mask = 0;
- unsigned offset = tex->image_offset[dst->u.tex.level][dst->u.tex.first_layer];
+ unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
assert(util_format_get_blockwidth(pt->format) == 1);
assert(util_format_get_blockheight(pt->format) == 1);
diff --git a/src/gallium/drivers/i915/i915_winsys.h b/src/gallium/drivers/i915/i915_winsys.h
index 5385e403d22..24ea416f015 100644
--- a/src/gallium/drivers/i915/i915_winsys.h
+++ b/src/gallium/drivers/i915/i915_winsys.h
@@ -53,6 +53,7 @@ enum i915_winsys_buffer_type
I915_NEW_VERTEX
};
+/* These need to be in sync with the definitions of libdrm-intel! */
enum i915_winsys_buffer_tile
{
I915_TILE_NONE,
@@ -106,7 +107,7 @@ struct i915_winsys {
int (*batchbuffer_reloc)(struct i915_winsys_batchbuffer *batch,
struct i915_winsys_buffer *reloc,
enum i915_winsys_buffer_usage usage,
- unsigned offset);
+ unsigned offset, bool fenced);
/**
* Flush a bufferbatch.
@@ -130,10 +131,24 @@ struct i915_winsys {
*/
struct i915_winsys_buffer *
(*buffer_create)(struct i915_winsys *iws,
- unsigned size, unsigned alignment,
+ unsigned size,
enum i915_winsys_buffer_type type);
/**
+ * Create a tiled buffer.
+ *
+ * *stride, height are in bytes. The winsys tries to allocate the buffer with
+ * the tiling mode provide in *tiling. If tiling is no possible, *tiling will
+ * be set to I915_TILE_NONE. The calculated stride (incorporateing hw/kernel
+ * requirements) is always returned in *stride.
+ */
+ struct i915_winsys_buffer *
+ (*buffer_create_tiled)(struct i915_winsys *iws,
+ unsigned *stride, unsigned height,
+ enum i915_winsys_buffer_tile *tiling,
+ enum i915_winsys_buffer_type type);
+
+ /**
* Creates a buffer from a handle.
* Used to implement pipe_screen::resource_from_handle.
* Also provides the stride information needed for the
@@ -142,6 +157,7 @@ struct i915_winsys {
struct i915_winsys_buffer *
(*buffer_from_handle)(struct i915_winsys *iws,
struct winsys_handle *whandle,
+ enum i915_winsys_buffer_tile *tiling,
unsigned *stride);
/**
@@ -154,15 +170,6 @@ struct i915_winsys {
unsigned stride);
/**
- * Fence a buffer with a fence reg.
- * Not to be confused with pipe_fence_handle.
- */
- int (*buffer_set_fence_reg)(struct i915_winsys *iws,
- struct i915_winsys_buffer *buffer,
- unsigned stride,
- enum i915_winsys_buffer_tile tile);
-
- /**
* Map a buffer.
*/
void *(*buffer_map)(struct i915_winsys *iws,