i915: Made vbuf work

This commit is contained in:
Jakob Bornecrantz 2008-05-27 13:18:25 +02:00
parent 938d9d5963
commit 08130512b9
2 changed files with 228 additions and 24 deletions

View file

@ -62,8 +62,14 @@ struct i915_vbuf_render {
/** Vertex size in bytes */
unsigned vertex_size;
/** Software primitive */
unsigned prim;
/** Hardware primitive */
unsigned hwprim;
/** Genereate a vertex list */
unsigned fallback;
};
@ -95,8 +101,8 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
static void *
i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
ushort vertex_size,
ushort nr_vertices )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
@ -107,9 +113,9 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
assert(!i915->vbo);
i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX,
size);
i915->dirty |= I915_NEW_VBO;
return winsys->buffer_map(winsys,
i915->vbo,
PIPE_BUFFER_USAGE_CPU_WRITE);
@ -121,16 +127,36 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
unsigned prim )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
i915_render->prim = prim;
switch(prim) {
case PIPE_PRIM_POINTS:
i915_render->hwprim = PRIM3D_POINTLIST;
i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_LINES:
i915_render->hwprim = PRIM3D_LINELIST;
i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_LINE_STRIP:
i915_render->hwprim = PRIM3D_LINESTRIP;
i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_TRIANGLES:
i915_render->hwprim = PRIM3D_TRILIST;
i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_TRIANGLE_STRIP:
i915_render->hwprim = PRIM3D_TRISTRIP;
i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_QUADS:
i915_render->hwprim = PRIM3D_TRILIST;
i915_render->fallback = PIPE_PRIM_QUADS;
return TRUE;
case PIPE_PRIM_QUAD_STRIP:
i915_render->hwprim = PRIM3D_TRILIST;
i915_render->fallback = PIPE_PRIM_QUAD_STRIP;
return TRUE;
default:
/* Actually, can handle a lot more just fine... Fixme.
@ -140,6 +166,179 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
}
/**
* Used for fallbacks in draw_arrays
*/
static void
draw_arrays_generate_indices( struct vbuf_render *render,
unsigned start, uint nr,
unsigned type )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
unsigned i;
unsigned end = start + nr;
switch(type) {
case 0:
for (i = start; i+1 < end; i += 2)
OUT_BATCH( (i+0) | (i+1) << 16 );
if (i < end)
OUT_BATCH( i );
break;
case PIPE_PRIM_QUADS:
for (i = start; i + 3 < end; i += 4) {
OUT_BATCH( (i+0) | (i+1) << 16 );
OUT_BATCH( (i+3) | (i+1) << 16 );
OUT_BATCH( (i+2) | (i+3) << 16 );
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = start; i + 3 < end; i += 2) {
OUT_BATCH( (i+0) | (i+1) << 16 );
OUT_BATCH( (i+3) | (i+2) << 16 );
OUT_BATCH( (i+0) | (i+3) << 16 );
}
break;
default:
assert(0);
}
}
static unsigned
draw_arrays_calc_nr_indices( uint nr, unsigned type )
{
switch (type) {
case 0:
return nr;
case PIPE_PRIM_QUADS:
return (nr / 4) * 6;
case PIPE_PRIM_QUAD_STRIP:
return ((nr - 2) / 2) * 6;
default:
assert(0);
return 0;
}
}
static void
draw_arrays_fallback( struct vbuf_render *render,
unsigned start,
uint nr )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
struct pipe_winsys *winsys = i915->pipe.winsys;
unsigned nr_indices;
winsys->buffer_unmap( winsys, i915->vbo );
if (i915->dirty)
i915_update_derived( i915 );
if (i915->hardware_dirty)
i915_emit_hardware_state( i915 );
nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback );
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/
i915_update_derived( i915 );
i915_emit_hardware_state( i915 );
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
assert(0);
goto out;
}
}
OUT_BATCH( _3DPRIMITIVE |
PRIM_INDIRECT |
i915_render->hwprim |
PRIM_INDIRECT_ELTS |
nr_indices );
draw_arrays_generate_indices( render, start, nr, i915_render->fallback );
out:
winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE );
}
static void
i915_vbuf_render_draw_arrays( struct vbuf_render *render,
unsigned start,
uint nr )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
if (i915_render->fallback) {
draw_arrays_fallback( render, start, nr );
return;
}
/* JB: TODO submit direct cmds */
draw_arrays_fallback( render, start, nr );
}
/**
* Used for normal and fallback emitting of indices
* If type is zero normal operation assumed.
*/
static void
draw_generate_indices( struct vbuf_render *render,
const ushort *indices,
uint nr_indices,
unsigned type )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
unsigned i;
switch(type) {
case 0:
for (i = 0; i + 1 < nr_indices; i += 2) {
OUT_BATCH( (indices[i] & 0x0FFF) | ((indices[i+1] & 0x0FFF) << 16) );
}
if (i < nr_indices) {
OUT_BATCH( indices[i] & 0x0FFF );
}
break;
case PIPE_PRIM_QUADS:
for (i = 0; i + 3 < nr_indices; i += 4) {
OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 );
OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 );
OUT_BATCH( (indices[i+2] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 );
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i + 3 < nr_indices; i += 2) {
OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 );
OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+2] & 0x0FFF) << 16 );
OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 );
}
break;
default:
assert(0);
break;
}
}
static unsigned
draw_calc_nr_indices( uint nr_indices, unsigned type )
{
switch (type) {
case 0:
return nr_indices;
case PIPE_PRIM_QUADS:
return (nr_indices / 4) * 6;
case PIPE_PRIM_QUAD_STRIP:
return ((nr_indices - 2) / 2) * 6;
default:
assert(0);
return 0;
}
}
static void
i915_vbuf_render_draw( struct vbuf_render *render,
const ushort *indices,
@ -147,13 +346,15 @@ i915_vbuf_render_draw( struct vbuf_render *render,
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
unsigned i;
struct pipe_winsys *winsys = i915->pipe.winsys;
unsigned save_nr_indices;
save_nr_indices = nr_indices;
nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback );
assert(nr_indices);
winsys->buffer_unmap( winsys, i915->vbo );
/* this seems to be bogus, since we validate state right after this */
/*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/
if (i915->dirty)
i915_update_derived( i915 );
@ -170,22 +371,23 @@ i915_vbuf_render_draw( struct vbuf_render *render,
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
assert(0);
return;
goto out;
}
}
OUT_BATCH( _3DPRIMITIVE |
PRIM_INDIRECT |
i915_render->hwprim |
PRIM_INDIRECT_ELTS |
nr_indices );
for (i = 0; i + 1 < nr_indices; i += 2) {
OUT_BATCH( indices[i] |
(indices[i + 1] << 16) );
}
if (i < nr_indices) {
OUT_BATCH( indices[i] );
}
PRIM_INDIRECT |
i915_render->hwprim |
PRIM_INDIRECT_ELTS |
nr_indices );
draw_generate_indices( render,
indices,
save_nr_indices,
i915_render->fallback );
out:
winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE );
return;
}
@ -234,6 +436,7 @@ i915_vbuf_render_create( struct i915_context *i915 )
i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
i915_render->base.draw = i915_vbuf_render_draw;
i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays;
i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
i915_render->base.destroy = i915_vbuf_render_destroy;
@ -258,6 +461,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
render->destroy(render);
return NULL;
}
draw_set_render(i915->draw, render);
return stage;
}

View file

@ -328,8 +328,8 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan )
DRM_BO_FLAG_READ |
DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_MEM_TT,
32 * 4096,
1, 40, 32 * 4096 * 2, 0,
128,
6, 120, 32 * 4096, 0,
fMan);
}