diff options
Diffstat (limited to 'src/gallium')
30 files changed, 392 insertions, 254 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, diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 48c24092114..583e981a4d2 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -424,4 +424,5 @@ void r300_parse_chipset(struct r300_capabilities* caps) } caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350; + caps->dxtc_swizzle = caps->is_r400 || caps->is_r500; } diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h index e7ca642b4f3..7ea4175dbee 100644 --- a/src/gallium/drivers/r300/r300_chipset.h +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -79,6 +79,8 @@ struct r300_capabilities { boolean is_r500; /* Whether or not the second pixel pipe is accessed with the high bit */ boolean high_second_pipe; + /* DXTC texture swizzling. */ + boolean dxtc_swizzle; }; /* Enumerations for legibility and telling which card we're running on. */ diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 6bea783f697..788c513be75 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -1520,11 +1520,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_TRI_PERF_3_8 (3<<15) # define R300_ANISO_THRESHOLD_MASK (7<<17) +# define R400_DXTC_SWIZZLE_ENABLE (1<<21) # define R500_MACRO_SWITCH (1<<22) # define R500_TX_MAX_ANISO(x) ((x) << 23) # define R500_TX_MAX_ANISO_MASK (63 << 23) # define R500_TX_ANISO_HIGH_QUALITY (1 << 30) - # define R500_BORDER_FIX (1<<31) #define R300_TX_FORMAT0_0 0x4480 diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 85de60df0f4..09981cb26b8 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -116,8 +116,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: - case PIPE_CAP_TEXTURE_SWIZZLE: return 1; + case PIPE_CAP_TEXTURE_SWIZZLE: + return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; /* Unsupported features (boolean caps). */ case PIPE_CAP_TIMER_QUERY: diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 509e3106a45..0f563703c06 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1347,6 +1347,7 @@ r300_create_sampler_view(struct pipe_context *pipe, struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view); struct r300_texture *tex = r300_texture(texture); boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500; + boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle; if (view) { view->base = *templ; @@ -1363,7 +1364,8 @@ r300_create_sampler_view(struct pipe_context *pipe, view->format = tex->tx_format; view->format.format1 |= r300_translate_texformat(templ->format, view->swizzle, - is_r500); + is_r500, + dxtc_swizzle); if (is_r500) { view->format.format2 |= r500_tx_format_msb_bit(templ->format); } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 5722c91ecec..a6d07760515 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -764,13 +764,18 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) { texstate->format.format1 |= r300_get_swizzle_combined(depth_swizzle, - view->swizzle); + view->swizzle, FALSE); } else { texstate->format.format1 |= - r300_get_swizzle_combined(depth_swizzle, 0); + r300_get_swizzle_combined(depth_swizzle, 0, FALSE); } } + if (r300->screen->caps.dxtc_swizzle && + util_format_is_compressed(tex->desc.b.b.format)) { + texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE; + } + /* to emulate 1D textures through 2D ones correctly */ if (tex->desc.b.b.target == PIPE_TEXTURE_1D) { texstate->filter0 &= ~R300_TX_WRAP_T_MASK; diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index fe8859ab8f0..4b7b3e03564 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -40,7 +40,8 @@ #include "pipe/p_screen.h" unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, - const unsigned char *swizzle_view) + const unsigned char *swizzle_view, + boolean dxtc_swizzle) { unsigned i; unsigned char swizzle[4]; @@ -51,10 +52,10 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, R300_TX_FORMAT_B_SHIFT, R300_TX_FORMAT_A_SHIFT }; - const uint32_t swizzle_bit[4] = { - R300_TX_FORMAT_X, + uint32_t swizzle_bit[4] = { + dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X, R300_TX_FORMAT_Y, - R300_TX_FORMAT_Z, + dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z, R300_TX_FORMAT_W }; @@ -107,7 +108,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ uint32_t r300_translate_texformat(enum pipe_format format, const unsigned char *swizzle_view, - boolean is_r500) + boolean is_r500, + boolean dxtc_swizzle) { uint32_t result = 0; const struct util_format_description *desc; @@ -169,7 +171,8 @@ uint32_t r300_translate_texformat(enum pipe_format format, } } - result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view); + result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, + util_format_is_compressed(format) && dxtc_swizzle); /* S3TC formats. */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { @@ -571,7 +574,7 @@ boolean r300_is_zs_format_supported(enum pipe_format format) boolean r300_is_sampler_format_supported(enum pipe_format format) { - return r300_translate_texformat(format, 0, TRUE) != ~0; + return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0; } void r300_texture_setup_format_state(struct r300_screen *screen, diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index be2740efc3b..0ab22f747e4 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -36,11 +36,13 @@ struct r300_texture; struct r300_screen; unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, - const unsigned char *swizzle_view); + const unsigned char *swizzle_view, + boolean dxtc_swizzle); uint32_t r300_translate_texformat(enum pipe_format format, const unsigned char *swizzle_view, - boolean is_r500); + boolean is_r500, + boolean dxtc_swizzle); uint32_t r500_tx_format_msb_bit(enum pipe_format format); diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 33448bf0def..15a323989b2 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -57,7 +57,7 @@ static unsigned translate_opcode(unsigned opcode) /* case TGSI_OPCODE_DP2A: return RC_OPCODE_DP2A; */ /* gap */ case TGSI_OPCODE_FRC: return RC_OPCODE_FRC; - /* case TGSI_OPCODE_CLAMP: return RC_OPCODE_CLAMP; */ + case TGSI_OPCODE_CLAMP: return RC_OPCODE_CLAMP; case TGSI_OPCODE_FLR: return RC_OPCODE_FLR; /* case TGSI_OPCODE_ROUND: return RC_OPCODE_ROUND; */ case TGSI_OPCODE_EX2: return RC_OPCODE_EX2; diff --git a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c index c6daa52a379..ebe86dcf196 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c +++ b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c @@ -14,9 +14,6 @@ #define INTEL_BATCH_CLIPRECTS 0x2 #undef INTEL_RUN_SYNC -#undef INTEL_MAP_BATCHBUFFER -#undef INTEL_MAP_GTT -#define INTEL_ALWAYS_FLUSH struct i915_drm_batchbuffer { @@ -72,11 +69,7 @@ i915_drm_batchbuffer_create(struct i915_winsys *iws) batch->actual_size = idws->max_batch_size; -#ifdef INTEL_MAP_BATCHBUFFER - batch->base.map = NULL; -#else batch->base.map = MALLOC(batch->actual_size); -#endif batch->base.ptr = NULL; batch->base.size = 0; @@ -94,7 +87,7 @@ static int i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch, struct i915_winsys_buffer *buffer, enum i915_winsys_buffer_usage usage, - unsigned pre_add) + unsigned pre_add, bool fenced) { struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch); unsigned write_domain = 0; @@ -104,37 +97,44 @@ i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch, assert(batch->base.relocs < batch->base.max_relocs); - if (usage == I915_USAGE_SAMPLER) { + switch (usage) { + case I915_USAGE_SAMPLER: write_domain = 0; read_domain = I915_GEM_DOMAIN_SAMPLER; - - } else if (usage == I915_USAGE_RENDER) { + break; + case I915_USAGE_RENDER: write_domain = I915_GEM_DOMAIN_RENDER; read_domain = I915_GEM_DOMAIN_RENDER; - - } else if (usage == I915_USAGE_2D_TARGET) { + break; + case I915_USAGE_2D_TARGET: write_domain = I915_GEM_DOMAIN_RENDER; read_domain = I915_GEM_DOMAIN_RENDER; - - } else if (usage == I915_USAGE_2D_SOURCE) { + break; + case I915_USAGE_2D_SOURCE: write_domain = 0; read_domain = I915_GEM_DOMAIN_RENDER; - - } else if (usage == I915_USAGE_VERTEX) { + break; + case I915_USAGE_VERTEX: write_domain = 0; read_domain = I915_GEM_DOMAIN_VERTEX; - - } else { + break; + default: assert(0); return -1; } offset = (unsigned)(batch->base.ptr - batch->base.map); - ret = drm_intel_bo_emit_reloc(batch->bo, offset, - intel_bo(buffer), pre_add, - read_domain, - write_domain); + if (fenced) + ret = drm_intel_bo_emit_reloc_fence(batch->bo, offset, + intel_bo(buffer), pre_add, + read_domain, + write_domain); + else + ret = drm_intel_bo_emit_reloc(batch->bo, offset, + intel_bo(buffer), pre_add, + read_domain, + write_domain); ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add; batch->base.ptr += 4; @@ -150,70 +150,32 @@ i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch, struct pipe_fence_handle **fence) { struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch); - unsigned used = 0; - int ret = 0; + unsigned used; + int ret; - assert(i915_winsys_batchbuffer_space(ibatch) >= 0); + /* MI_BATCH_BUFFER_END */ + i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23)); used = batch->base.ptr - batch->base.map; - assert((used & 3) == 0); - - -#ifdef INTEL_ALWAYS_FLUSH - /* MI_FLUSH | FLUSH_MAP_CACHE */ - i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0)); - used += 4; -#endif - - if ((used & 4) == 0) { + if (used & 4) { /* MI_NOOP */ - i915_winsys_batchbuffer_dword(ibatch, 0); + i915_winsys_batchbuffer_dword_unchecked(ibatch, 0); + used += 4; } - /* MI_BATCH_BUFFER_END */ - i915_winsys_batchbuffer_dword(ibatch, (0xA<<23)); - - used = batch->base.ptr - batch->base.map; - assert((used & 4) == 0); - -#ifdef INTEL_MAP_BATCHBUFFER -#ifdef INTEL_MAP_GTT - drm_intel_gem_bo_unmap_gtt(batch->bo); -#else - drm_intel_bo_unmap(batch->bo); -#endif -#else - drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map); -#endif /* Do the sending to HW */ - if (i915_drm_winsys(ibatch->iws)->send_cmd) + ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map); + if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd) ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); - else - ret = 0; if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) { -#ifdef INTEL_MAP_BATCHBUFFER -#ifdef INTEL_MAP_GTT - drm_intel_gem_bo_map_gtt(batch->bo); -#else - drm_intel_bo_map(batch->bo, 0); -#endif -#endif i915_dump_batchbuffer(ibatch); assert(ret == 0); -#ifdef INTEL_MAP_BATCHBUFFER -#ifdef INTEL_MAP_GTT - drm_intel_gem_bo_unmap_gtt(batch->bo); -#else - drm_intel_bo_unmap(batch->bo); -#endif -#endif - } else { + } + #ifdef INTEL_RUN_SYNC - drm_intel_bo_map(batch->bo, FALSE); - drm_intel_bo_unmap(batch->bo); + drm_intel_bo_wait_rendering(batch->bo); #endif - } if (fence) { ibatch->iws->fence_reference(ibatch->iws, fence, NULL); @@ -237,9 +199,7 @@ i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch) if (batch->bo) drm_intel_bo_unreference(batch->bo); -#ifndef INTEL_MAP_BATCHBUFFER FREE(batch->base.map); -#endif FREE(batch); } diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c index 15ec4487457..01dd4bf062f 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_buffer.c +++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c @@ -5,14 +5,31 @@ #include "i915_drm.h" +static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type) +{ + char *name; + + if (type == I915_NEW_TEXTURE) { + name = "gallium3d_texture"; + } else if (type == I915_NEW_VERTEX) { + name = "gallium3d_vertex"; + } else if (type == I915_NEW_SCANOUT) { + name = "gallium3d_scanout"; + } else { + assert(0); + name = "gallium3d_unknown"; + } + + return name; +} + static struct i915_winsys_buffer * i915_drm_buffer_create(struct i915_winsys *iws, - unsigned size, unsigned alignment, + unsigned size, enum i915_winsys_buffer_type type) { struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); struct i915_drm_winsys *idws = i915_drm_winsys(iws); - char *name; if (!buf) return NULL; @@ -21,22 +38,48 @@ i915_drm_buffer_create(struct i915_winsys *iws, buf->flinked = FALSE; buf->flink = 0; - if (type == I915_NEW_TEXTURE) { - name = "gallium3d_texture"; - } else if (type == I915_NEW_VERTEX) { - name = "gallium3d_vertex"; - } else if (type == I915_NEW_SCANOUT) { - name = "gallium3d_scanout"; - } else { - assert(0); - name = "gallium3d_unknown"; - } + buf->bo = drm_intel_bo_alloc(idws->gem_manager, + i915_drm_type_to_name(type), size, 0); - buf->bo = drm_intel_bo_alloc(idws->gem_manager, name, size, alignment); + if (!buf->bo) + goto err; + + return (struct i915_winsys_buffer *)buf; + +err: + assert(0); + FREE(buf); + return NULL; +} + +static struct i915_winsys_buffer * +i915_drm_buffer_create_tiled(struct i915_winsys *iws, + unsigned *stride, unsigned height, + enum i915_winsys_buffer_tile *tiling, + enum i915_winsys_buffer_type type) +{ + struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); + struct i915_drm_winsys *idws = i915_drm_winsys(iws); + unsigned long pitch = 0; + uint32_t tiling_mode = *tiling; + + if (!buf) + return NULL; + + buf->magic = 0xDEAD1337; + buf->flinked = FALSE; + buf->flink = 0; + + buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager, + i915_drm_type_to_name(type), + *stride, height, 1, + &tiling_mode, &pitch, 0); if (!buf->bo) goto err; + *stride = pitch; + *tiling = tiling_mode; return (struct i915_winsys_buffer *)buf; err: @@ -47,8 +90,9 @@ err: static struct i915_winsys_buffer * i915_drm_buffer_from_handle(struct i915_winsys *iws, - struct winsys_handle *whandle, - unsigned *stride) + struct winsys_handle *whandle, + enum i915_winsys_buffer_tile *tiling, + unsigned *stride) { struct i915_drm_winsys *idws = i915_drm_winsys(iws); struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); @@ -68,6 +112,7 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws, drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle); *stride = whandle->stride; + *tiling = tile; return (struct i915_winsys_buffer *)buf; @@ -103,24 +148,6 @@ i915_drm_buffer_get_handle(struct i915_winsys *iws, return TRUE; } -static int -i915_drm_buffer_set_fence_reg(struct i915_winsys *iws, - struct i915_winsys_buffer *buffer, - unsigned stride, - enum i915_winsys_buffer_tile tile) -{ - struct i915_drm_buffer *buf = i915_drm_buffer(buffer); - assert(I915_TILING_NONE == I915_TILE_NONE); - assert(I915_TILING_X == I915_TILE_X); - assert(I915_TILING_Y == I915_TILE_Y); - - if (tile != I915_TILE_NONE) { - assert(buf->map_count == 0); - } - - return drm_intel_bo_set_tiling(buf->bo, &tile, stride); -} - static void * i915_drm_buffer_map(struct i915_winsys *iws, struct i915_winsys_buffer *buffer, @@ -190,9 +217,9 @@ void i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws) { idws->base.buffer_create = i915_drm_buffer_create; + idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled; idws->base.buffer_from_handle = i915_drm_buffer_from_handle; idws->base.buffer_get_handle = i915_drm_buffer_get_handle; - idws->base.buffer_set_fence_reg = i915_drm_buffer_set_fence_reg; idws->base.buffer_map = i915_drm_buffer_map; idws->base.buffer_unmap = i915_drm_buffer_unmap; idws->base.buffer_write = i915_drm_buffer_write; diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.c b/src/gallium/winsys/i915/drm/i915_drm_winsys.c index cc0b6a99577..2288b48b2bd 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_winsys.c +++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.c @@ -69,6 +69,7 @@ i915_drm_winsys_create(int drmFD) idws->gem_manager = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size); drm_intel_bufmgr_gem_enable_reuse(idws->gem_manager); + drm_intel_bufmgr_gem_enable_fenced_relocs(idws->gem_manager); idws->dump_cmd = debug_get_bool_option("I915_DUMP_CMD", FALSE); idws->send_cmd = !debug_get_bool_option("I915_NO_HW", FALSE); diff --git a/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c index a480cfed57b..44773ae30e7 100644 --- a/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c +++ b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c @@ -61,7 +61,7 @@ static int i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch, struct i915_winsys_buffer *buffer, enum i915_winsys_buffer_usage usage, - unsigned pre_add) + unsigned pre_add, bool fenced) { struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch); int ret = 0; diff --git a/src/gallium/winsys/i915/sw/i915_sw_buffer.c b/src/gallium/winsys/i915/sw/i915_sw_buffer.c index df175688861..834805e621d 100644 --- a/src/gallium/winsys/i915/sw/i915_sw_buffer.c +++ b/src/gallium/winsys/i915/sw/i915_sw_buffer.c @@ -4,28 +4,15 @@ static struct i915_winsys_buffer * i915_sw_buffer_create(struct i915_winsys *iws, - unsigned size, unsigned alignment, + unsigned size, enum i915_winsys_buffer_type type) { struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer); - char *name; if (!buf) return NULL; - if (type == I915_NEW_TEXTURE) { - name = "gallium3d_texture"; - } else if (type == I915_NEW_VERTEX) { - name = "gallium3d_vertex"; - } else if (type == I915_NEW_SCANOUT) { - name = "gallium3d_scanout"; - } else { - assert(0); - name = "gallium3d_unknown"; - } - buf->magic = 0xDEAD1337; - buf->name = name; buf->type = type; buf->ptr = CALLOC(size, 1); @@ -40,21 +27,32 @@ err: return NULL; } -static int -i915_sw_buffer_set_fence_reg(struct i915_winsys *iws, - struct i915_winsys_buffer *buffer, - unsigned stride, - enum i915_winsys_buffer_tile tile) +static struct i915_winsys_buffer * +i915_sw_buffer_create_tiled(struct i915_winsys *iws, + unsigned *stride, unsigned height, + enum i915_winsys_buffer_tile *tiling, + enum i915_winsys_buffer_type type) { - struct i915_sw_buffer *buf = i915_sw_buffer(buffer); + struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer); + + if (!buf) + return NULL; + + buf->magic = 0xDEAD1337; + buf->type = type; + buf->ptr = CALLOC(*stride * height, 1); + buf->tiling = *tiling; + buf->stride = *stride; - if (tile != I915_TILE_NONE) { - assert(buf->map_count == 0); - } + if (!buf->ptr) + goto err; - buf->tile = tile; + return (struct i915_winsys_buffer *)buf; - return 0; +err: + assert(0); + FREE(buf); + return NULL; } static void * @@ -108,7 +106,7 @@ void i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *isws) { isws->base.buffer_create = i915_sw_buffer_create; - isws->base.buffer_set_fence_reg = i915_sw_buffer_set_fence_reg; + isws->base.buffer_create_tiled = i915_sw_buffer_create_tiled; isws->base.buffer_map = i915_sw_buffer_map; isws->base.buffer_unmap = i915_sw_buffer_unmap; isws->base.buffer_write = i915_sw_buffer_write; diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.h b/src/gallium/winsys/i915/sw/i915_sw_winsys.h index b7b43669f30..3af2548419e 100644 --- a/src/gallium/winsys/i915/sw/i915_sw_winsys.h +++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.h @@ -43,8 +43,8 @@ struct i915_sw_buffer { void *ptr; unsigned map_count; enum i915_winsys_buffer_type type; - enum i915_winsys_buffer_tile tile; - const char *name; + enum i915_winsys_buffer_tile tiling; + unsigned stride; }; static INLINE struct i915_sw_buffer * |