summaryrefslogtreecommitdiffstats
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/i915_context.c27
-rw-r--r--src/gallium/drivers/i915/i915_context.h14
-rw-r--r--src/gallium/drivers/i915/i915_debug.c3
-rw-r--r--src/gallium/drivers/i915/i915_prim_vbuf.c16
-rw-r--r--src/gallium/drivers/i915/i915_resource_buffer.c39
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c16
-rw-r--r--src/gallium/drivers/i915/i915_screen.h16
-rw-r--r--src/gallium/drivers/i915/i915_state.c45
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c3
-rw-r--r--src/gallium/drivers/i915/i915_state_fpc.c2
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
};