0,0 → 1,776 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
|
/** |
* \file |
* Build post-transformation, post-clipping vertex buffers and element |
* lists by hooking into the end of the primitive pipeline and |
* manipulating the vertex_id field in the vertex headers. |
* |
* XXX: work in progress |
* |
* \author José Fonseca <jfonseca@vmware.com> |
* \author Keith Whitwell <keithw@vmware.com> |
*/ |
|
|
#include "draw/draw_context.h" |
#include "draw/draw_vbuf.h" |
#include "util/u_debug.h" |
#include "util/u_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" |
#include "i915_batch.h" |
#include "i915_state.h" |
|
|
#define VBUF_MAP_BUFFER |
|
/** |
* Primitive renderer for i915. |
*/ |
struct i915_vbuf_render { |
struct vbuf_render base; |
|
struct i915_context *i915; |
|
/** Vertex size in bytes */ |
size_t vertex_size; |
|
/** Software primitive */ |
unsigned prim; |
|
/** Hardware primitive */ |
unsigned hwprim; |
|
/** Genereate a vertex list */ |
unsigned fallback; |
|
/* Stuff for the vbo */ |
struct i915_winsys_buffer *vbo; |
size_t vbo_size; /**< current size of allocated buffer */ |
size_t vbo_alloc_size; /**< minimum buffer size to allocate */ |
size_t vbo_hw_offset; /**< offset that we program the hardware with */ |
size_t vbo_sw_offset; /**< offset that we work with */ |
size_t vbo_index; /**< index offset to be added to all indices */ |
void *vbo_ptr; |
size_t vbo_max_used; |
size_t vbo_max_index; /**< index offset to be added to all indices */ |
|
#ifndef VBUF_MAP_BUFFER |
size_t map_used_start; |
size_t map_used_end; |
size_t map_size; |
#endif |
}; |
|
|
/** |
* Basically a cast wrapper. |
*/ |
static INLINE struct i915_vbuf_render * |
i915_vbuf_render(struct vbuf_render *render) |
{ |
assert(render); |
return (struct i915_vbuf_render *)render; |
} |
|
/** |
* If vbo state differs between renderer and context |
* push state to the context. This function pushes |
* hw_offset to i915->vbo_offset and vbo to i915->vbo. |
* |
* Side effects: |
* May updates context vbo_offset and vbo fields. |
*/ |
static void |
i915_vbuf_update_vbo_state(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
|
if (i915->vbo != i915_render->vbo || |
i915->vbo_offset != i915_render->vbo_hw_offset) { |
i915->vbo = i915_render->vbo; |
i915->vbo_offset = i915_render->vbo_hw_offset; |
i915->dirty |= I915_NEW_VBO; |
} |
} |
|
/** |
* Callback exported to the draw module. |
* Returns the current vertex_info. |
* |
* Side effects: |
* If state is dirty update derived state. |
*/ |
static const struct vertex_info * |
i915_vbuf_render_get_vertex_info(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
|
if (i915->dirty) { |
/* make sure we have up to date vertex layout */ |
i915_update_derived(i915); |
} |
|
return &i915->current.vertex_info; |
} |
|
/** |
* Reserve space in the vbo for vertices. |
* |
* Side effects: |
* None. |
*/ |
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_sw_offset) |
return FALSE; |
|
if (i915->vbo_flushed) |
return FALSE; |
|
return TRUE; |
} |
|
/** |
* Allocate a new vbo buffer should there not be enough space for |
* the requested number of vertices by the draw module. |
* |
* Side effects: |
* Updates hw_offset, sw_offset, index and allocates a new buffer. |
* Will set i915->vbo to null on buffer allocation. |
*/ |
static void |
i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size) |
{ |
struct i915_context *i915 = i915_render->i915; |
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 |
* update_vbo_state but since they arn't and malloc likes to reuse |
* memory we need to set it to null |
*/ |
i915->vbo = NULL; |
i915_render->vbo = NULL; |
} |
|
i915->vbo_flushed = 0; |
|
i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size); |
i915_render->vbo_hw_offset = 0; |
i915_render->vbo_sw_offset = 0; |
i915_render->vbo_index = 0; |
|
#ifndef VBUF_MAP_BUFFER |
if (i915_render->vbo_size > i915_render->map_size) { |
i915_render->map_size = i915_render->vbo_size; |
FREE(i915_render->vbo_ptr); |
i915_render->vbo_ptr = MALLOC(i915_render->map_size); |
} |
#endif |
|
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); |
} |
|
/** |
* Callback exported to the draw module. |
* |
* Side effects: |
* Updates hw_offset, sw_offset, index and may allocate |
* a new buffer. Also updates may update the vbo state |
* on the i915 context. |
*/ |
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); |
size_t size = (size_t)vertex_size * (size_t)nr_vertices; |
size_t offset; |
|
/* |
* Align sw_offset with first multiple of vertex size from hw_offset. |
* Set index to be the multiples from from hw_offset to sw_offset. |
* i915_vbuf_render_new_buf will reset index, sw_offset, hw_offset |
* when it allocates a new buffer this is correct. |
*/ |
{ |
offset = i915_render->vbo_sw_offset - i915_render->vbo_hw_offset; |
offset = util_align_npot(offset, vertex_size); |
i915_render->vbo_sw_offset = i915_render->vbo_hw_offset + offset; |
i915_render->vbo_index = offset / vertex_size; |
} |
|
if (!i915_vbuf_render_reserve(i915_render, size)) |
i915_vbuf_render_new_buf(i915_render, size); |
|
/* |
* If a new buffer has been alocated sw_offset, |
* hw_offset & index will be reset by new_buf |
*/ |
|
i915_render->vertex_size = vertex_size; |
|
i915_vbuf_update_vbo_state(render); |
|
if (!i915_render->vbo) |
return FALSE; |
return TRUE; |
} |
|
static void * |
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; |
|
if (i915->vbo_flushed) |
debug_printf("%s bad vbo flush occurred stalling on hw\n", __FUNCTION__); |
|
#ifdef VBUF_MAP_BUFFER |
return (unsigned char *)i915_render->vbo_ptr + i915_render->vbo_sw_offset; |
#else |
return (unsigned char *)i915_render->vbo_ptr; |
#endif |
} |
|
static void |
i915_vbuf_render_unmap_vertices(struct vbuf_render *render, |
ushort min_index, |
ushort max_index) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
struct i915_winsys *iws = i915->iws; |
|
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 |
(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); |
iws->buffer_write(iws, i915_render->vbo, |
i915_render->map_used_start + i915_render->vbo_sw_offset, |
i915_render->map_used_end - i915_render->map_used_start, |
(unsigned char *)i915_render->vbo_ptr + i915_render->map_used_start); |
|
#endif |
} |
|
/** |
* Ensure that the given max_index given is not larger ushort max. |
* If it is larger then ushort max it advanced the hw_offset to the |
* same position in the vbo as sw_offset and set index to zero. |
* |
* Side effects: |
* On failure update hw_offset and index. |
*/ |
static void |
i915_vbuf_ensure_index_bounds(struct vbuf_render *render, |
unsigned max_index) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
|
if (max_index + i915_render->vbo_index < ((1 << 17) - 1)) |
return; |
|
i915_render->vbo_hw_offset = i915_render->vbo_sw_offset; |
i915_render->vbo_index = 0; |
|
i915_vbuf_update_vbo_state(render); |
} |
|
static void |
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; |
break; |
case PIPE_PRIM_LINES: |
i915_render->hwprim = PRIM3D_LINELIST; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_LINE_LOOP: |
i915_render->hwprim = PRIM3D_LINELIST; |
i915_render->fallback = PIPE_PRIM_LINE_LOOP; |
break; |
case PIPE_PRIM_LINE_STRIP: |
i915_render->hwprim = PRIM3D_LINESTRIP; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_TRIANGLES: |
i915_render->hwprim = PRIM3D_TRILIST; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_TRIANGLE_STRIP: |
i915_render->hwprim = PRIM3D_TRISTRIP; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_TRIANGLE_FAN: |
i915_render->hwprim = PRIM3D_TRIFAN; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_QUADS: |
i915_render->hwprim = PRIM3D_TRILIST; |
i915_render->fallback = PIPE_PRIM_QUADS; |
break; |
case PIPE_PRIM_QUAD_STRIP: |
i915_render->hwprim = PRIM3D_TRILIST; |
i915_render->fallback = PIPE_PRIM_QUAD_STRIP; |
break; |
case PIPE_PRIM_POLYGON: |
i915_render->hwprim = PRIM3D_POLY; |
i915_render->fallback = 0; |
break; |
default: |
/* FIXME: Actually, can handle a lot more just fine... */ |
assert(0 && "unexpected prim in i915_vbuf_render_set_primitive()"); |
} |
} |
|
/** |
* 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 + i915_render->vbo_index; |
start += i915_render->vbo_index; |
|
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_LINE_LOOP: |
if (nr >= 2) { |
for (i = start + 1; i < end; i++) |
OUT_BATCH((i-1) | (i+0) << 16); |
OUT_BATCH((i-1) | ( start) << 16); |
} |
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_LINE_LOOP: |
if (nr >= 2) |
return nr * 2; |
else |
return 0; |
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; |
unsigned nr_indices; |
|
nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback); |
if (!nr_indices) |
return; |
|
i915_vbuf_ensure_index_bounds(render, start + nr_indices); |
|
if (i915->dirty) |
i915_update_derived(i915); |
|
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
|
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
|
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
|
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
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); |
struct i915_context *i915 = i915_render->i915; |
|
if (i915_render->fallback) { |
draw_arrays_fallback(render, start, nr); |
return; |
} |
|
i915_vbuf_ensure_index_bounds(render, start + nr); |
start += i915_render->vbo_index; |
|
if (i915->dirty) |
i915_update_derived(i915); |
|
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
|
if (!BEGIN_BATCH(2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
|
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
|
if (!BEGIN_BATCH(2)) { |
assert(0); |
goto out; |
} |
} |
|
OUT_BATCH(_3DPRIMITIVE | |
PRIM_INDIRECT | |
PRIM_INDIRECT_SEQUENTIAL | |
i915_render->hwprim | |
nr); |
OUT_BATCH(start); /* Beginning vertex index */ |
|
out: |
return; |
} |
|
/** |
* 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; |
unsigned o = i915_render->vbo_index; |
|
switch(type) { |
case 0: |
for (i = 0; i + 1 < nr_indices; i += 2) { |
OUT_BATCH((o+indices[i]) | (o+indices[i+1]) << 16); |
} |
if (i < nr_indices) { |
OUT_BATCH((o+indices[i])); |
} |
break; |
case PIPE_PRIM_LINE_LOOP: |
if (nr_indices >= 2) { |
for (i = 1; i < nr_indices; i++) |
OUT_BATCH((o+indices[i-1]) | (o+indices[i]) << 16); |
OUT_BATCH((o+indices[i-1]) | (o+indices[0]) << 16); |
} |
break; |
case PIPE_PRIM_QUADS: |
for (i = 0; i + 3 < nr_indices; i += 4) { |
OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16); |
OUT_BATCH((o+indices[i+3]) | (o+indices[i+1]) << 16); |
OUT_BATCH((o+indices[i+2]) | (o+indices[i+3]) << 16); |
} |
break; |
case PIPE_PRIM_QUAD_STRIP: |
for (i = 0; i + 3 < nr_indices; i += 2) { |
OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16); |
OUT_BATCH((o+indices[i+3]) | (o+indices[i+2]) << 16); |
OUT_BATCH((o+indices[i+0]) | (o+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_LINE_LOOP: |
if (nr_indices >= 2) |
return nr_indices * 2; |
else |
return 0; |
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_elements(struct vbuf_render *render, |
const ushort *indices, |
uint nr_indices) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
unsigned save_nr_indices; |
|
save_nr_indices = nr_indices; |
|
nr_indices = draw_calc_nr_indices(nr_indices, i915_render->fallback); |
if (!nr_indices) |
return; |
|
i915_vbuf_ensure_index_bounds(render, i915_render->vbo_max_index); |
|
if (i915->dirty) |
i915_update_derived(i915); |
|
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
|
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
|
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
|
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
assert(0); |
goto out; |
} |
} |
|
OUT_BATCH(_3DPRIMITIVE | |
PRIM_INDIRECT | |
i915_render->hwprim | |
PRIM_INDIRECT_ELTS | |
nr_indices); |
draw_generate_indices(render, |
indices, |
save_nr_indices, |
i915_render->fallback); |
|
out: |
return; |
} |
|
static void |
i915_vbuf_render_release_vertices(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
|
i915_render->vbo_sw_offset += i915_render->vbo_max_used; |
i915_render->vbo_max_used = 0; |
|
/* |
* Micro optimization, by calling update here we the offset change |
* will be picked up on the next pipe_context::draw_*. |
*/ |
i915_vbuf_update_vbo_state(render); |
} |
|
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); |
} |
|
/** |
* Create a new primitive render. |
*/ |
static struct vbuf_render * |
i915_vbuf_render_create(struct i915_context *i915) |
{ |
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render); |
struct i915_winsys *iws = i915->iws; |
int i; |
|
i915_render->i915 = i915; |
|
i915_render->base.max_vertex_buffer_bytes = 4*4096; |
|
/* NOTE: it must be such that state and vertices indices fit in a single |
* batch buffer. 4096 is one batch buffer and 430 is the max amount of |
* state in dwords. The result is the number of 16-bit indices which can |
* fit in a single batch buffer. |
*/ |
i915_render->base.max_indices = (4096 - 430 * 4) / 2; |
|
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.map_vertices = i915_vbuf_render_map_vertices; |
i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices; |
i915_render->base.set_primitive = i915_vbuf_render_set_primitive; |
i915_render->base.draw_elements = i915_vbuf_render_draw_elements; |
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; |
|
#ifndef VBUF_MAP_BUFFER |
i915_render->map_size = 0; |
i915_render->map_used_start = 0; |
i915_render->map_used_end = 0; |
#endif |
|
i915_render->vbo = NULL; |
i915_render->vbo_ptr = NULL; |
i915_render->vbo_size = 0; |
i915_render->vbo_hw_offset = 0; |
i915_render->vbo_sw_offset = 0; |
i915_render->vbo_alloc_size = i915_render->base.max_vertex_buffer_bytes * 4; |
|
#ifdef VBUF_USE_POOL |
i915_render->pool_used = FALSE; |
i915_render->pool_buffer_size = i915_render->vbo_alloc_size; |
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, |
I915_NEW_VERTEX)); |
#else |
(void)i; |
(void)iws; |
#endif |
|
return &i915_render->base; |
} |
|
/** |
* Create a new primitive vbuf/render stage. |
*/ |
struct draw_stage *i915_draw_vbuf_stage(struct i915_context *i915) |
{ |
struct vbuf_render *render; |
struct draw_stage *stage; |
|
render = i915_vbuf_render_create(i915); |
if(!render) |
return NULL; |
|
stage = draw_vbuf_stage(i915->draw, render); |
if(!stage) { |
render->destroy(render); |
return NULL; |
} |
/** TODO JB: this shouldn't be here */ |
draw_set_render(i915->draw, render); |
|
return stage; |
} |