summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i915simple
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/i915simple')
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c7
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_vbuf.c129
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c10
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c49
-rw-r--r--src/gallium/drivers/i915simple/intel_winsys.h11
6 files changed, 183 insertions, 27 deletions
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index b43f735245..e745f3342d 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -175,12 +175,19 @@ i915_is_buffer_referenced(struct pipe_context *pipe,
static void i915_destroy(struct pipe_context *pipe)
{
struct i915_context *i915 = i915_context(pipe);
+ int i;
draw_destroy(i915->draw);
if(i915->batch)
i915->iws->batchbuffer_destroy(i915->batch);
+ /* unbind framebuffer */
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
+ }
+ pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
+
FREE(i915);
}
diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
index 508f4560e4..d50201642b 100644
--- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
@@ -44,6 +44,7 @@
#include "pipe/p_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_fifo.h"
#include "i915_context.h"
#include "i915_reg.h"
@@ -76,8 +77,13 @@ struct i915_vbuf_render {
size_t vbo_size;
size_t vbo_offset;
void *vbo_ptr;
- size_t vbo_alloc_size;
size_t vbo_max_used;
+
+ /* stuff for the pool */
+ struct util_fifo *pool_fifo;
+ unsigned pool_used;
+ unsigned pool_buffer_size;
+ boolean pool_not_used;
};
@@ -106,33 +112,72 @@ i915_vbuf_render_get_vertex_info(struct vbuf_render *render)
}
static boolean
+i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
+{
+ struct i915_context *i915 = i915_render->i915;
+
+ if (i915_render->vbo_size < size + i915_render->vbo_offset)
+ return FALSE;
+
+ if (i915->vbo_flushed)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
+{
+ struct i915_context *i915 = i915_render->i915;
+ struct intel_winsys *iws = i915->iws;
+
+ if (i915_render->vbo) {
+ if (i915_render->pool_not_used)
+ iws->buffer_destroy(iws, i915_render->vbo);
+ else
+ u_fifo_add(i915_render->pool_fifo, i915_render->vbo);
+ i915_render->vbo = NULL;
+ }
+
+ i915->vbo_flushed = 0;
+
+ i915_render->vbo_size = MAX2(size, i915_render->pool_buffer_size);
+ i915_render->vbo_offset = 0;
+
+ if (i915_render->vbo_size != i915_render->pool_buffer_size) {
+ i915_render->pool_not_used = TRUE;
+ i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
+ INTEL_NEW_VERTEX);
+ } else {
+ i915_render->pool_not_used = FALSE;
+
+ if (i915_render->pool_used >= 2) {
+ FLUSH_BATCH(NULL);
+ i915->vbo_flushed = 0;
+ i915_render->pool_used = 0;
+ }
+ u_fifo_pop(i915_render->pool_fifo, (void**)&i915_render->vbo);
+ }
+}
+
+static boolean
i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
size_t size = (size_t)vertex_size * (size_t)nr_vertices;
/* FIXME: handle failure */
assert(!i915->vbo);
- if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
- } else {
- i915->vbo_flushed = 0;
- if (i915_render->vbo) {
- iws->buffer_destroy(iws, i915_render->vbo);
- i915_render->vbo = NULL;
- }
- }
+ if (!i915_vbuf_render_reserve(i915_render, size)) {
- if (!i915_render->vbo) {
- i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
- i915_render->vbo_offset = 0;
- i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
- INTEL_NEW_VERTEX);
+ if (i915->vbo_flushed)
+ i915_render->pool_used = 0;
+ i915_vbuf_render_new_buf(i915_render, size);
}
i915_render->vertex_size = vertex_size;
@@ -153,7 +198,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render)
struct intel_winsys *iws = i915->iws;
if (i915->vbo_flushed)
- debug_printf("%s bad vbo flush occured stalling on hw\n");
+ debug_printf("%s bad vbo flush occured stalling on hw\n", __func__);
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
@@ -344,14 +389,43 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
uint nr)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
if (i915_render->fallback) {
draw_arrays_fallback(render, start, nr);
return;
}
- /* JB: TODO submit direct cmds */
- draw_arrays_fallback(render, start, nr);
+ if (i915->dirty)
+ i915_update_derived(i915);
+
+ if (i915->hardware_dirty)
+ i915_emit_hardware_state(i915);
+
+ if (!BEGIN_BATCH(2, 0)) {
+ FLUSH_BATCH(NULL);
+
+ /* Make sure state is re-emitted after a flush:
+ */
+ i915_update_derived(i915);
+ i915_emit_hardware_state(i915);
+ i915->vbo_flushed = 1;
+
+ if (!BEGIN_BATCH(2, 0)) {
+ assert(0);
+ goto out;
+ }
+ }
+
+ OUT_BATCH(_3DPRIMITIVE |
+ PRIM_INDIRECT |
+ PRIM_INDIRECT_SEQUENTIAL |
+ i915_render->hwprim |
+ nr);
+ OUT_BATCH(start); /* Beginning vertex index */
+
+out:
+ return;
}
/**
@@ -504,6 +578,7 @@ i915_vbuf_render_create(struct i915_context *i915)
{
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
struct intel_winsys *iws = i915->iws;
+ int i;
i915_render->i915 = i915;
@@ -524,14 +599,24 @@ i915_vbuf_render_create(struct i915_context *i915)
i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
i915_render->base.destroy = i915_vbuf_render_destroy;
- i915_render->vbo_alloc_size = 128 * 4096;
- i915_render->vbo_size = i915_render->vbo_alloc_size;
+
+ i915_render->vbo = NULL;
+ i915_render->vbo_size = 0;
i915_render->vbo_offset = 0;
- i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
- INTEL_NEW_VERTEX);
+
+ i915_render->pool_used = FALSE;
+ i915_render->pool_buffer_size = 128 * 4096;
+ 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,
+ INTEL_NEW_VERTEX));
+
+#if 0
/* TODO JB: is this realy needed? */
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
iws->buffer_unmap(iws, i915_render->vbo);
+#endif
return &i915_render->base;
}
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index 9f017a14cc..c66558c320 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -46,7 +46,7 @@
static const char *
i915_get_vendor(struct pipe_screen *screen)
{
- return "Tungsten Graphics, Inc.";
+ return "VMware, Inc.";
}
static const char *
@@ -101,8 +101,6 @@ i915_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 0087dfa410..7d48e6e84d 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -588,9 +588,17 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct i915_context *i915 = i915_context(pipe);
+ int i;
+
draw_flush(i915->draw);
- i915->framebuffer = *fb; /* struct copy */
+ i915->framebuffer.width = fb->width;
+ i915->framebuffer.height = fb->height;
+ i915->framebuffer.nr_cbufs = fb->nr_cbufs;
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]);
+ }
+ pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf);
i915->dirty |= I915_NEW_FRAMEBUFFER;
}
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index 6a6c654271..15ccc1fc73 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -165,7 +165,7 @@ i915_scanout_layout(struct i915_texture *tex)
struct pipe_texture *pt = &tex->base;
if (pt->last_level > 0 || pt->block.size != 4)
- return 0;
+ return FALSE;
i915_miptree_set_level_info(tex, 0, 1,
tex->base.width[0],
@@ -191,6 +191,38 @@ i915_scanout_layout(struct i915_texture *tex)
return TRUE;
}
+/**
+ * Special case to deal with shared textures.
+ */
+static boolean
+i915_display_target_layout(struct i915_texture *tex)
+{
+ struct pipe_texture *pt = &tex->base;
+
+ if (pt->last_level > 0 || pt->block.size != 4)
+ return FALSE;
+
+ /* fallback to normal textures for small textures */
+ if (tex->base.width[0] < 240)
+ return FALSE;
+
+ i915_miptree_set_level_info(tex, 0, 1,
+ tex->base.width[0],
+ tex->base.height[0],
+ 1);
+ i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
+
+ tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
+ tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
+ tex->hw_tiled = INTEL_TILE_X;
+
+ debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
+ tex->base.width[0], tex->base.height[0], pt->block.size,
+ tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
+
+ return TRUE;
+}
+
static void
i915_miptree_layout_2d(struct i915_texture *tex)
{
@@ -201,6 +233,16 @@ i915_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
+ /* used for scanouts that need special layouts */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (i915_scanout_layout(tex))
+ return;
+
+ /* for shared buffers we use some very like scanout */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ if (i915_display_target_layout(tex))
+ return;
+
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->total_nblocksy = 0;
@@ -351,6 +393,11 @@ i945_miptree_layout_2d(struct i915_texture *tex)
if (i915_scanout_layout(tex))
return;
+ /* for shared buffers we use some very like scanout */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ if (i915_display_target_layout(tex))
+ return;
+
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
/* May need to adjust pitch to accomodate the placement of
diff --git a/src/gallium/drivers/i915simple/intel_winsys.h b/src/gallium/drivers/i915simple/intel_winsys.h
index f949f52a9c..42c5e7470e 100644
--- a/src/gallium/drivers/i915simple/intel_winsys.h
+++ b/src/gallium/drivers/i915simple/intel_winsys.h
@@ -150,6 +150,17 @@ struct intel_winsys {
void (*buffer_unmap)(struct intel_winsys *iws,
struct intel_buffer *buffer);
+ /**
+ * Write to a buffer.
+ *
+ * Arguments follows pwrite(2)
+ */
+ int (*buffer_write)(struct intel_winsys *iws,
+ struct intel_buffer *dst,
+ const void *src,
+ size_t size,
+ size_t offset);
+
void (*buffer_destroy)(struct intel_winsys *iws,
struct intel_buffer *buffer);
/*@}*/