diff options
Diffstat (limited to 'src/gallium/drivers/i915simple')
-rw-r--r-- | src/gallium/drivers/i915simple/i915_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/i915simple/i915_flush.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/i915simple/i915_prim_vbuf.c | 306 | ||||
-rw-r--r-- | src/gallium/drivers/i915simple/i915_state.c | 26 | ||||
-rw-r--r-- | src/gallium/drivers/i915simple/i915_state_emit.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/i915simple/i915_state_immediate.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/i915simple/i915_texture.c | 154 |
7 files changed, 390 insertions, 102 deletions
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 53fc5ed079..2da90ae49d 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -245,6 +245,8 @@ struct i915_context /** Vertex buffer */ struct pipe_buffer *vbo; + size_t vbo_offset; + unsigned vbo_flushed; struct i915_state current; unsigned hardware_dirty; diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 7d23e6b6b9..4c4718d68e 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -68,6 +68,7 @@ static void i915_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ FLUSH_BATCH(fence); + i915->vbo_flushed = 1; } diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index 7fb2adbb53..faf5971abb 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -62,8 +62,21 @@ 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; + + /* Stuff for the vbo */ + struct pipe_buffer *vbo; + size_t vbo_size; + size_t vbo_offset; + void *vbo_ptr; + size_t vbo_alloc_size; }; @@ -95,8 +108,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; @@ -105,14 +118,31 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render, /* FIXME: handle failure */ assert(!i915->vbo); - i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX, - size); - + + if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) { + } else { + i915->vbo_flushed = 0; + pipe_buffer_reference(winsys, &i915_render->vbo, NULL); + } + + if (!i915_render->vbo) { + i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size); + i915_render->vbo_offset = 0; + i915_render->vbo = winsys->buffer_create(winsys, + 64, + I915_BUFFER_USAGE_LIT_VERTEX, + i915_render->vbo_size); + i915_render->vbo_ptr = winsys->buffer_map(winsys, + i915_render->vbo, + PIPE_BUFFER_USAGE_CPU_WRITE); + winsys->buffer_unmap(winsys, i915_render->vbo); + } + + i915->vbo = i915_render->vbo; + i915->vbo_offset = i915_render->vbo_offset; i915->dirty |= I915_NEW_VBO; - - return winsys->buffer_map(winsys, - i915->vbo, - PIPE_BUFFER_USAGE_CPU_WRITE); + + return i915_render->vbo_ptr + i915->vbo_offset; } @@ -121,16 +151,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 +190,180 @@ 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; + + 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 ); + i915->vbo_flushed = 1; + + 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: + return; +} + +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] | indices[i+1] << 16 ); + } + if (i < nr_indices) { + OUT_BATCH( indices[i] ); + } + break; + case PIPE_PRIM_QUADS: + for (i = 0; i + 3 < nr_indices; i += 4) { + OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); + OUT_BATCH( indices[i+3] | indices[i+1] << 16 ); + OUT_BATCH( indices[i+2] | indices[i+3] << 16 ); + } + break; + case PIPE_PRIM_QUAD_STRIP: + for (i = 0; i + 3 < nr_indices; i += 2) { + OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); + OUT_BATCH( indices[i+3] | indices[i+2] << 16 ); + OUT_BATCH( indices[i+0] | indices[i+3] << 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 +371,14 @@ 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); - /* 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 ); @@ -167,25 +392,26 @@ i915_vbuf_render_draw( struct vbuf_render *render, */ i915_update_derived( i915 ); i915_emit_hardware_state( i915 ); + i915->vbo_flushed = 1; 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: + return; } @@ -198,10 +424,13 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render, struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; struct pipe_winsys *winsys = i915->pipe.winsys; + size_t size = (size_t)vertex_size * (size_t)vertices_used; assert(i915->vbo); - winsys->buffer_unmap(winsys, i915->vbo); - pipe_buffer_reference(winsys, &i915->vbo, NULL); + + i915_render->vbo_offset += size; + i915->vbo = NULL; + i915->dirty |= I915_NEW_VBO; } @@ -220,6 +449,7 @@ static struct vbuf_render * i915_vbuf_render_create( struct i915_context *i915 ) { struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render); + struct pipe_winsys *winsys = i915->pipe.winsys; i915_render->i915 = i915; @@ -229,14 +459,27 @@ i915_vbuf_render_create( struct i915_context *i915 ) * batch buffer. */ i915_render->base.max_indices = 16*1024; - + i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info; 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; - + + i915_render->vbo_alloc_size = 128 * 4096; + i915_render->vbo_size = i915_render->vbo_alloc_size; + i915_render->vbo_offset = 0; + i915_render->vbo = winsys->buffer_create(winsys, + 64, + I915_BUFFER_USAGE_LIT_VERTEX, + i915_render->vbo_size); + i915_render->vbo_ptr = winsys->buffer_map(winsys, + i915_render->vbo, + PIPE_BUFFER_USAGE_CPU_WRITE); + winsys->buffer_unmap(winsys, i915_render->vbo); + return &i915_render->base; } @@ -258,6 +501,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; } diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e09c225900..39d5d5e9d6 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -41,7 +41,6 @@ #include "i915_state_inlines.h" #include "i915_fpc.h" - /* The i915 (and related graphics cores) do not support GL_CLAMP. The * Intel drivers for "other operating systems" implement GL_CLAMP as * GL_CLAMP_TO_EDGE, so the same is done here. @@ -178,6 +177,7 @@ static void i915_bind_blend_state(struct pipe_context *pipe, void *blend) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->blend = (struct i915_blend_state*)blend; @@ -194,6 +194,7 @@ static void i915_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->blend_color = *blend_color; @@ -280,6 +281,8 @@ static void i915_bind_sampler_states(struct pipe_context *pipe, !memcmp(i915->sampler, sampler, num * sizeof(void *))) return; + draw_flush(i915->draw); + for (i = 0; i < num; ++i) i915->sampler[i] = sampler[i]; for (i = num; i < PIPE_MAX_SAMPLERS; ++i) @@ -398,6 +401,7 @@ static void i915_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; @@ -415,6 +419,7 @@ static void i915_set_scissor_state( struct pipe_context *pipe, const struct pipe_scissor_state *scissor ) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); memcpy( &i915->scissor, scissor, sizeof(*scissor) ); i915->dirty |= I915_NEW_SCISSOR; @@ -451,6 +456,7 @@ static void i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->fs = (struct i915_fragment_shader*) shader; @@ -506,6 +512,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); struct pipe_winsys *ws = pipe->winsys; + draw_flush(i915->draw); assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -574,6 +581,7 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->framebuffer = *fb; /* struct copy */ @@ -586,6 +594,7 @@ static void i915_set_clip_state( struct pipe_context *pipe, const struct pipe_clip_state *clip ) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); draw_set_clip_state(i915->draw, clip); @@ -698,6 +707,10 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_context(pipe); + /* Because we change state before the draw_set_vertex_buffers call + * we need a flush here, just to be sure. + */ + draw_flush(i915->draw); memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0])); i915->num_vertex_buffers = count; @@ -711,16 +724,27 @@ static void i915_set_vertex_elements(struct pipe_context *pipe, const struct pipe_vertex_element *elements) { struct i915_context *i915 = i915_context(pipe); + /* Because we change state before the draw_set_vertex_buffers call + * we need a flush here, just to be sure. + */ + draw_flush(i915->draw); + i915->num_vertex_elements = count; /* pass-through to draw module */ draw_set_vertex_elements(i915->draw, count, elements); } +static void i915_set_edgeflags(struct pipe_context *pipe, + const unsigned *bitfield) +{ + /* TODO do something here */ +} void i915_init_state_functions( struct i915_context *i915 ) { + i915->pipe.set_edgeflags = i915_set_edgeflags; i915->pipe.create_blend_state = i915_create_blend_state; i915->pipe.bind_blend_state = i915_bind_blend_state; i915->pipe.delete_blend_state = i915_delete_blend_state; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 6f947d4346..8bcc26ad35 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -217,6 +217,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_BATCH(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(pitch) | /* pitch in bytes */ +// BUF_3D_TILED_SURFACE); /* JB: Used to force tileing */ BUF_3D_USE_FENCE); OUT_RELOC(cbuf_surface->buffer, diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index dfbbcab624..704ea4d838 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -54,7 +54,7 @@ static void upload_S0S1(struct i915_context *i915) /* INTEL_NEW_VBO */ /* TODO: re-use vertex buffers here? */ - LIS0 = 0; + LIS0 = i915->vbo_offset; /* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated! */ diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 3e23e540f9..4c0c7ce3f3 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -104,52 +104,50 @@ i915_miptree_set_image_offset(struct i915_texture *tex, */ } +static unsigned +power_of_two(unsigned x) +{ + int value = 1; + while (value <= x) + value = value << 1; + return value; +} + +static unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} -/* Hack it up to use the old winsys->surface_alloc_storage() - * method for now: +/** + * Special case to deal with display targets. */ static boolean i915_displaytarget_layout(struct pipe_screen *screen, struct i915_texture *tex) { - struct pipe_winsys *ws = screen->winsys; - struct pipe_surface surf; - unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); - - - memset(&surf, 0, sizeof(surf)); - - ws->surface_alloc_storage( ws, - &surf, - tex->base.width[0], - tex->base.height[0], - tex->base.format, - flags, - tex->base.tex_usage); - - /* Now extract the goodies: - */ - i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); - i915_miptree_set_level_info( tex, 0, 0, 0, 0, + struct pipe_texture *pt = &tex->base; + + if (pt->last_level > 0 || pt->cpp != 4) + return 0; + + i915_miptree_set_level_info( tex, 0, 1, 0, 0, tex->base.width[0], tex->base.height[0], 1 ); + i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); - tex->buffer = surf.buffer; - tex->pitch = surf.pitch; - tex->total_height = 0; - +#if 0 + tex->pitch = MAX2(512, power_of_two(tex->base.width[0] * pt->cpp)) / pt->cpp; + tex->total_height = round_up(tex->base.height[0], 8); +#else + tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); + tex->total_height = tex->base.height[0]; +#endif - return tex->buffer != NULL; + return 1; } - - - - static void i945_miptree_layout_2d( struct i915_texture *tex ) { @@ -179,7 +177,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) /* Pitch must be a whole number of dwords, even though we * express it in texels. */ - tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp; + tex->pitch = align_int(tex->pitch * pt->cpp, 64) / pt->cpp; tex->total_height = 0; for (level = 0; level <= pt->last_level; level++) { @@ -525,54 +523,47 @@ i945_miptree_layout(struct i915_texture * tex) static struct pipe_texture * -i915_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) +i915_texture_create(struct pipe_screen *screen, + const struct pipe_texture *templat) { struct i915_screen *i915screen = i915_screen(screen); struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); - if (!tex) + if (!tex) return NULL; tex->base = *templat; tex->base.refcount = 1; tex->base.screen = screen; - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - if (!i915_displaytarget_layout(screen, tex)) - goto fail; - } - else { - if (i915screen->is_i945) { - if (!i945_miptree_layout(tex)) - goto fail; - } - else { - if (!i915_miptree_layout(tex)) - goto fail; - } - - tex->buffer = ws->buffer_create(ws, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); - - if (!tex->buffer) - goto fail; + if (i915screen->is_i945) { + if (!i945_miptree_layout(tex)) + goto fail; + } else { + if (!i915_miptree_layout(tex)) + goto fail; } + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) + goto fail; + return &tex->base; - fail: +fail: FREE(tex); return NULL; } static void -i915_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) +i915_texture_release(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -606,10 +597,10 @@ i915_texture_release_screen(struct pipe_screen *screen, * XXX note: same as code in sp_surface.c */ static struct pipe_surface * -i915_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) +i915_get_tex_surface(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct i915_texture *tex = (struct i915_texture *)pt; struct pipe_winsys *ws = screen->winsys; @@ -629,10 +620,11 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, assert(zslice == 0); } - ps = ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface);//ws->surface_alloc(ws); if (ps) { assert(ps->refcount); assert(ps->winsys); + pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; ps->cpp = pt->cpp; @@ -652,11 +644,35 @@ i915_init_texture_functions(struct i915_context *i915) // i915->pipe.texture_update = i915_texture_update; } +static void +i915_tex_surface_release(struct pipe_screen *screen, + struct pipe_surface **surface) +{ + struct pipe_surface *surf = *surface; + + if (--surf->refcount == 0) { + + /* This really should not be possible, but it's actually + * happening quite a bit... Will fix. + */ + if (surf->status == PIPE_SURFACE_STATUS_CLEAR) { + debug_printf("XXX destroying a surface with pending clears...\n"); + assert(0); + } + + pipe_texture_reference(&surf->texture, NULL); + pipe_buffer_reference(screen->winsys, &surf->buffer, NULL); + FREE(surf); + } + + *surface = NULL; +} void i915_init_screen_texture_functions(struct pipe_screen *screen) { - screen->texture_create = i915_texture_create_screen; - screen->texture_release = i915_texture_release_screen; - screen->get_tex_surface = i915_get_tex_surface_screen; + screen->texture_create = i915_texture_create; + screen->texture_release = i915_texture_release; + screen->get_tex_surface = i915_get_tex_surface; + screen->tex_surface_release = i915_tex_surface_release; } |