diff options
Diffstat (limited to 'src/gallium/drivers/i915')
-rw-r--r-- | src/gallium/drivers/i915/i915_context.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_context.h | 14 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_debug.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_prim_vbuf.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_resource_buffer.c | 39 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_resource_texture.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_screen.h | 16 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state.c | 45 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state_emit.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state_fpc.c | 2 |
10 files changed, 125 insertions, 56 deletions
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 9be31619254..ea3c10b5e78 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -51,6 +51,14 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) struct draw_context *draw = i915->draw; void *mapped_indices = NULL; unsigned i; + unsigned cbuf_dirty; + + + /* + * Ack vs contants here, helps ipers a lot. + */ + cbuf_dirty = i915->dirty & I915_NEW_VS_CONSTANTS; + i915->dirty &= ~I915_NEW_VS_CONSTANTS; if (i915->dirty) i915_update_derived(i915); @@ -70,10 +78,12 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; draw_set_mapped_index_buffer(draw, mapped_indices); - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, - i915->current.constants[PIPE_SHADER_VERTEX], - (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * - 4 * sizeof(float))); + if (cbuf_dirty) { + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, + i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, + (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * + 4 * sizeof(float))); + } /* * Do the drawing @@ -117,6 +127,11 @@ static void i915_destroy(struct pipe_context *pipe) } pipe_surface_reference(&i915->framebuffer.zsbuf, NULL); + /* unbind constant buffers */ + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + pipe_resource_reference(&i915->constants[i], NULL); + } + FREE(i915); } @@ -140,6 +155,10 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915->base.draw_vbo = i915_draw_vbo; + /* init this before draw */ + util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer), + 16, UTIL_SLAB_SINGLETHREADED); + /* * Create drawing context and plug our rendering stage into it. */ diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index d15e1723d83..b7f1fb22221 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -37,6 +37,8 @@ #include "tgsi/tgsi_scan.h" +#include "util/u_slab.h" + struct i915_winsys; struct i915_winsys_buffer; @@ -134,7 +136,6 @@ struct i915_state unsigned immediate[I915_MAX_IMMEDIATE]; unsigned dynamic[I915_MAX_DYNAMIC]; - float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; /** number of constants passed in through a constant buffer */ uint num_user_constants[PIPE_SHADER_TYPES]; @@ -212,7 +213,6 @@ struct i915_context { struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; - /* XXX unneded */ struct pipe_resource *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; @@ -237,6 +237,8 @@ struct i915_context { struct i915_state current; unsigned hardware_dirty; + + struct util_slab_mempool transfer_pool; }; /* A flag for each state_tracker state object: @@ -253,9 +255,11 @@ struct i915_context { #define I915_NEW_DEPTH_STENCIL 0x200 #define I915_NEW_SAMPLER 0x400 #define I915_NEW_SAMPLER_VIEW 0x800 -#define I915_NEW_CONSTANTS 0x1000 -#define I915_NEW_VBO 0x2000 -#define I915_NEW_VS 0x4000 +#define I915_NEW_VS_CONSTANTS 0x1000 +#define I915_NEW_FS_CONSTANTS 0x2000 +#define I915_NEW_GS_CONSTANTS 0x4000 +#define I915_NEW_VBO 0x8000 +#define I915_NEW_VS 0x10000 /* Driver's internally generated state flags: diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c index 87c435a2f36..845e92cf5c6 100644 --- a/src/gallium/drivers/i915/i915_debug.c +++ b/src/gallium/drivers/i915/i915_debug.c @@ -948,7 +948,8 @@ i915_dump_dirty(struct i915_context *i915, const char *func) {I915_NEW_DEPTH_STENCIL, "depth_stencil"}, {I915_NEW_SAMPLER, "sampler"}, {I915_NEW_SAMPLER_VIEW, "sampler_view"}, - {I915_NEW_CONSTANTS, "constants"}, + {I915_NEW_VS_CONSTANTS, "vs_const"}, + {I915_NEW_FS_CONSTANTS, "fs_const"}, {I915_NEW_VBO, "vbo"}, {I915_NEW_VS, "vs"}, {0, NULL}, diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c index baebbc7bae3..3473c863970 100644 --- a/src/gallium/drivers/i915/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915/i915_prim_vbuf.c @@ -181,6 +181,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size) struct i915_winsys *iws = i915->iws; if (i915_render->vbo) { + iws->buffer_unmap(iws, i915_render->vbo); iws->buffer_destroy(iws, i915_render->vbo); /* * XXX If buffers where referenced then this should be done in @@ -208,6 +209,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size) i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, I915_NEW_VERTEX); + i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE); } /** @@ -262,16 +264,13 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct i915_winsys *iws = i915->iws; if (i915->vbo_flushed) debug_printf("%s bad vbo flush occured stalling on hw\n", __FUNCTION__); #ifdef VBUF_MAP_BUFFER - i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE); return (unsigned char *)i915_render->vbo_ptr + i915_render->vbo_sw_offset; #else - (void)iws; return (unsigned char *)i915_render->vbo_ptr; #endif } @@ -288,7 +287,7 @@ i915_vbuf_render_unmap_vertices(struct vbuf_render *render, i915_render->vbo_max_index = max_index; i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1)); #ifdef VBUF_MAP_BUFFER - iws->buffer_unmap(iws, i915_render->vbo); + (void)iws; #else i915_render->map_used_start = i915_render->vertex_size * min_index; i915_render->map_used_end = i915_render->vertex_size * (max_index + 1); @@ -684,6 +683,15 @@ static void i915_vbuf_render_destroy(struct vbuf_render *render) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + struct i915_winsys *iws = i915->iws; + + if (i915_render->vbo) { + i915->vbo = NULL; + iws->buffer_unmap(iws, i915_render->vbo); + iws->buffer_destroy(iws, i915_render->vbo); + } + FREE(i915_render); } diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c index 450203d60a9..51482f54fc4 100644 --- a/src/gallium/drivers/i915/i915_resource_buffer.c +++ b/src/gallium/drivers/i915/i915_resource_buffer.c @@ -60,6 +60,38 @@ i915_buffer_destroy(struct pipe_screen *screen, } +static struct pipe_transfer * +i915_get_transfer(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box) +{ + struct i915_context *i915 = i915_context(pipe); + struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); + + if (transfer == NULL) + return NULL; + + transfer->resource = resource; + transfer->level = level; + transfer->usage = usage; + transfer->box = *box; + + /* Note strides are zero, this is ok for buffers, but not for + * textures 2d & higher at least. + */ + return transfer; +} + +static void +i915_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct i915_context *i915 = i915_context(pipe); + util_slab_free(&i915->transfer_pool, transfer); +} + static void * i915_buffer_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) @@ -92,8 +124,8 @@ struct u_resource_vtbl i915_buffer_vtbl = i915_buffer_get_handle, /* get_handle */ i915_buffer_destroy, /* resource_destroy */ NULL, /* is_resource_referenced */ - u_default_get_transfer, /* get_transfer */ - u_default_transfer_destroy, /* transfer_destroy */ + i915_get_transfer, /* get_transfer */ + i915_transfer_destroy, /* transfer_destroy */ i915_buffer_transfer_map, /* transfer_map */ u_default_transfer_flush_region, /* transfer_flush_region */ u_default_transfer_unmap, /* transfer_unmap */ @@ -115,8 +147,7 @@ i915_buffer_create(struct pipe_screen *screen, buf->b.vtbl = &i915_buffer_vtbl; pipe_reference_init(&buf->b.b.reference, 1); buf->b.b.screen = screen; - - buf->data = MALLOC(template->width0); + buf->data = align_malloc(template->width0, 16); buf->free_on_destroy = TRUE; if (!buf->data) diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index f19106f3414..e793d126ade 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -716,14 +716,16 @@ i915_texture_destroy(struct pipe_screen *screen, } static struct pipe_transfer * -i915_texture_get_transfer(struct pipe_context *context, +i915_texture_get_transfer(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, unsigned usage, const struct pipe_box *box) { + struct i915_context *i915 = i915_context(pipe); struct i915_texture *tex = i915_texture(resource); - struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer); + struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); + if (transfer == NULL) return NULL; @@ -737,6 +739,14 @@ i915_texture_get_transfer(struct pipe_context *context, return transfer; } +static void +i915_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct i915_context *i915 = i915_context(pipe); + util_slab_free(&i915->transfer_pool, transfer); +} + static void * i915_texture_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) @@ -781,7 +791,7 @@ struct u_resource_vtbl i915_texture_vtbl = i915_texture_destroy, /* resource_destroy */ NULL, /* is_resource_referenced */ i915_texture_get_transfer, /* get_transfer */ - u_default_transfer_destroy, /* transfer_destroy */ + i915_transfer_destroy, /* transfer_destroy */ i915_texture_transfer_map, /* transfer_map */ u_default_transfer_flush_region, /* transfer_flush_region */ i915_texture_transfer_unmap, /* transfer_unmap */ diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h index 0c4186c68ee..bb4d255a3b3 100644 --- a/src/gallium/drivers/i915/i915_screen.h +++ b/src/gallium/drivers/i915/i915_screen.h @@ -47,16 +47,6 @@ struct i915_screen boolean is_i945; }; -/** - * Subclass of pipe_transfer - */ -struct i915_transfer -{ - struct pipe_transfer base; - - unsigned offset; -}; - /* * Cast wrappers @@ -69,11 +59,5 @@ i915_screen(struct pipe_screen *pscreen) return (struct i915_screen *) pscreen; } -static INLINE struct i915_transfer * -i915_transfer(struct pipe_transfer *transfer) -{ - return (struct i915_transfer *)transfer; -} - #endif /* I915_SCREEN_H */ diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index f5b60ed5942..4a1a4a04f6d 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -525,29 +525,40 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, struct pipe_resource *buf) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); + unsigned new_num = 0; + boolean diff = TRUE; - /* Make a copy of shader constants. - * During fragment program translation we may add additional - * constants to the array. - * - * We want to consider the situation where some user constants - * (ex: a material color) may change frequently but the shader program - * stays the same. In that case we should only be updating the first - * N constants, leaving any extras from shader translation alone. - */ + + /* XXX don't support geom shaders now */ + if (shader == PIPE_SHADER_GEOMETRY) + return; + + /* if we have a new buffer compare it with the old one */ if (buf) { struct i915_buffer *ir = i915_buffer(buf); - memcpy(i915->current.constants[shader], ir->data, ir->b.b.width0); - i915->current.num_user_constants[shader] = (ir->b.b.width0 / - 4 * sizeof(float)); - } - else { - i915->current.num_user_constants[shader] = 0; + struct pipe_resource *old_buf = i915->constants[shader]; + struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL; + + new_num = ir->b.b.width0 / 4 * sizeof(float); + + if (old && new_num != i915->current.num_user_constants[shader]) + diff = memcmp(old->data, ir->data, ir->b.b.width0); + } else { + diff = i915->current.num_user_constants[shader] != 0; } + /* + * flush before updateing the state. + * XXX: looks like its okay to skip the flush for vertex cbufs + */ + if (diff && shader == PIPE_SHADER_FRAGMENT) + draw_flush(i915->draw); + + pipe_resource_reference(&i915->constants[shader], buf); + i915->current.num_user_constants[shader] = new_num; - i915->dirty |= I915_NEW_CONSTANTS; + if (diff) + i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; } diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 86c02976495..5a89977c26c 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -367,7 +367,8 @@ i915_emit_hardware_state(struct i915_context *i915 ) const uint *c; if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) { /* grab user-defined constant */ - c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i]; + c = (uint *) i915_buffer(i915->constants[PIPE_SHADER_FRAGMENT])->data; + c += 4 * i; } else { /* emit program constant */ diff --git a/src/gallium/drivers/i915/i915_state_fpc.c b/src/gallium/drivers/i915/i915_state_fpc.c index ec7cec0e471..1959a24691d 100644 --- a/src/gallium/drivers/i915/i915_state_fpc.c +++ b/src/gallium/drivers/i915/i915_state_fpc.c @@ -40,7 +40,7 @@ static void update_hw_constants(struct i915_context *i915) struct i915_tracked_state i915_hw_constants = { "hw_constants", update_hw_constants, - I915_NEW_CONSTANTS | I915_NEW_FS + I915_NEW_FS_CONSTANTS | I915_NEW_FS }; |