#define U_DRAWQUAD_H
+#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+
+
#ifdef __cplusplus
extern "C" {
#endif
struct pipe_resource;
+
+static INLINE void
+util_draw_init_info(struct pipe_draw_info *info)
+{
+ memset(info, 0, sizeof(*info));
+ info->instance_count = 1;
+ info->max_index = 0xffffffff;
+}
+
+
+static INLINE void
+util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count)
+{
+ struct pipe_draw_info info;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.min_index = start;
+ info.max_index = start + count - 1;
+
+ pipe->draw_vbo(pipe, &info);
+}
+
+
extern void
util_draw_vertex_buffer(struct pipe_context *pipe,
struct pipe_resource *vbuf, uint offset,
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
+ struct pipe_index_buffer index_buffer;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
+#include "util/u_draw_quad.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
* XXX should the element buffer be specified/bound with a separate function?
*/
static void
-cell_draw_range_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned min_index,
- unsigned max_index,
- unsigned mode, unsigned start, unsigned count)
+cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct cell_context *cell = cell_context(pipe);
struct draw_context *draw = cell->draw;
+ void *mapped_indices = NULL;
unsigned i;
if (cell->dirty)
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
- if (indexBuffer) {
- void *mapped_indexes = cell_resource(indexBuffer)->data;
- draw_set_mapped_element_buffer(draw, indexSize, indexBias, mapped_indexes);
- }
- else {
- /* no index/element buffer */
- draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+ if (info->indexed && cell->index_buffer.buffer) {
+ mapped_indices = cell_resource(cell->index_buffer.buffer)->data;
+ mapped_indices += cell->index_buffer.offset;
}
+ draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+ lp->index_buffer.index_size : 0,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ mapped_indices);
/* draw! */
- draw_arrays(draw, mode, start, count);
+ draw_arrays(draw, info->mode, info->start, info->count);
/*
* unmap vertex/index buffers - will cause draw module to flush
for (i = 0; i < cell->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
- if (indexBuffer) {
+ if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}
+static void
+cell_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_resource *indexBuffer,
+ unsigned indexSize,
+ int indexBias,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned mode, unsigned start, unsigned count)
+{
+ struct cell_context *cell = cell_context(pipe);
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.index_bias = indexBias;
+ info.min_index = min_index;
+ info.max_index = max_index;
+
+ if (indexBuffer) {
+ info.indexed = TRUE;
+ saved_ib = cell->index_buffer;
+
+ ib.buffer = indexBuffer;
+ ib.offset = 0;
+ ib.index_size = indexSize;
+ pipe->set_index_buffer(pipe, &ib);
+ }
+
+ cell_draw_vbo(pipe, &info);
+
+ if (indexBuffer)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
+
+
static void
cell_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
cell->pipe.draw_arrays = cell_draw_arrays;
cell->pipe.draw_elements = cell_draw_elements;
cell->pipe.draw_range_elements = cell_draw_range_elements;
+ cell->pipe.draw_vbo = cell_draw_vbo;
}
}
+static void
+cell_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ if (ib)
+ memcpy(&cell->index_buffer, ib, sizeof(cell->index_buffer));
+ else
+ memset(&cell->index_buffer, 0, sizeof(cell->index_buffer));
+
+ /* TODO make this more like a state */
+}
+
+
void
cell_init_vertex_functions(struct cell_context *cell)
{
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
+ cell->pipe.set_index_buffer = cell_set_index_buffer;
cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;
#include "pipe/p_defines.h"
#include "util/u_memory.h"
+#include "util/u_draw_quad.h"
#include "pipe/p_context.h"
#include "fo_context.h"
}
-static void failover_draw_elements( struct pipe_context *pipe,
- struct pipe_resource *indexResource,
- unsigned indexSize,
- int indexBias,
- unsigned prim,
- unsigned start,
- unsigned count)
+static void failover_draw_vbo( struct pipe_context *pipe,
+ const struct pipe_draw_info *info)
{
struct failover_context *failover = failover_context( pipe );
/* Try hardware:
*/
if (failover->mode == FO_HW) {
- failover->hw->draw_elements( failover->hw,
- indexResource,
- indexSize,
- indexBias,
- prim,
- start,
- count );
+ failover->hw->draw_vbo( failover->hw, info );
}
/* Possibly try software:
failover_state_emit( failover );
}
- failover->sw->draw_elements( failover->sw,
- indexResource,
- indexSize,
- indexBias,
- prim,
- start,
- count );
+ failover->sw->draw_vbo( failover->sw, info );
/* Be ready to switch back to hardware rendering without an
* intervening flush. Unlikely to be much performance impact to
}
+static void failover_draw_elements( struct pipe_context *pipe,
+ struct pipe_resource *indexResource,
+ unsigned indexSize,
+ int indexBias,
+ unsigned prim,
+ unsigned start,
+ unsigned count)
+{
+ struct failover_context *failover = failover_context( pipe );
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = prim;
+ info.start = start;
+ info.count = count;
+
+ if (indexResource) {
+ info.indexed = TRUE;
+ saved_ib = failover->index_buffer;
+
+ ib.buffer = indexResource;
+ ib.offset = 0;
+ ib.index_size = indexSize;
+ pipe->set_index_buffer(pipe, &ib);
+ }
+
+ failover_draw_vbo(pipe, &info);
+
+ if (indexResource)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
+
+
static void failover_draw_arrays( struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
{
failover->pipe.draw_arrays = failover_draw_arrays;
failover->pipe.draw_elements = failover_draw_elements;
+ failover->pipe.draw_vbo = failover_draw_vbo;
failover->pipe.clear = hw->clear;
failover->pipe.clear_render_target = hw->clear_render_target;
failover->pipe.clear_depth_stencil = hw->clear_depth_stencil;
#define FO_NEW_VERTEX_BUFFER 0x40000
#define FO_NEW_VERTEX_ELEMENT 0x80000
#define FO_NEW_SAMPLE_MASK 0x100000
+#define FO_NEW_INDEX_BUFFER 0x200000
struct pipe_scissor_state scissor;
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer index_buffer;
uint num_vertex_buffers;
}
+static void
+failover_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct failover_context *failover = failover_context(pipe);
+
+ if (ib)
+ memcpy(&failover->index_buffer, ib, sizeof(failover->index_buffer));
+ else
+ memset(&failover->index_buffer, 0, sizeof(failover->index_buffer));
+
+ failover->dirty |= FO_NEW_INDEX_BUFFER;
+ failover->sw->set_index_buffer( failover->sw, ib );
+ failover->hw->set_index_buffer( failover->hw, ib );
+}
+
+
void
failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
+ failover->pipe.set_index_buffer = failover_set_index_buffer;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
failover->pipe.create_sampler_view = failover_create_sampler_view;
failover->pipe.sampler_view_destroy = failover_sampler_view_destroy;
failover->vertex_buffers );
}
+ if (failover->dirty & FO_NEW_INDEX_BUFFER) {
+ failover->sw->set_index_buffer( failover->sw,
+ &failover->index_buffer );
+ }
+
failover->dirty = 0;
}
count);
}
+static void
+galahad_draw_vbo(struct pipe_context *_pipe,
+ const struct pipe_draw_info *info)
+{
+ struct galahad_context *glhd_pipe = galahad_context(_pipe);
+ struct pipe_context *pipe = glhd_pipe->pipe;
+
+ pipe->draw_vbo(pipe, info);
+}
+
static struct pipe_query *
galahad_create_query(struct pipe_context *_pipe,
unsigned query_type)
num_buffers,
buffers);
}
+
+static void
+galahad_set_index_buffer(struct pipe_context *_pipe,
+ const struct pipe_index_buffer *_ib)
+{
+ struct galahad_context *glhd_pipe = galahad_context(_pipe);
+ struct pipe_context *pipe = glhd_pipe->pipe;
+ struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+ if (_ib->buffer) {
+ switch (_ib->index_size) {
+ case 1:
+ case 2:
+ case 4:
+ break;
+ default:
+ glhd_warn("index buffer %p has unrecognized index size %d",
+ _ib->buffer, _ib->index_size);
+ break;
+ }
+ }
+ else if (_ib->offset || _ib->index_size) {
+ glhd_warn("non-indexed state with index offset %d and index size %d",
+ _ib->offset, _ib->index_size);
+ }
+
+ if (_ib) {
+ unwrapped_ib = *_ib;
+ unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer);
+ ib = &unwrapped_ib;
+ }
+
+ pipe->set_index_buffer(pipe, ib);
+}
+
static void
galahad_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *_dst,
glhd_pipe->base.draw_arrays = galahad_draw_arrays;
glhd_pipe->base.draw_elements = galahad_draw_elements;
glhd_pipe->base.draw_range_elements = galahad_draw_range_elements;
+ glhd_pipe->base.draw_vbo = galahad_draw_vbo;
glhd_pipe->base.create_query = galahad_create_query;
glhd_pipe->base.destroy_query = galahad_destroy_query;
glhd_pipe->base.begin_query = galahad_begin_query;
glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views;
glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views;
glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers;
+ glhd_pipe->base.set_index_buffer = galahad_set_index_buffer;
glhd_pipe->base.resource_copy_region = galahad_resource_copy_region;
glhd_pipe->base.clear = galahad_clear;
glhd_pipe->base.clear_render_target = galahad_clear_render_target;
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
+#include "util/u_draw_quad.h"
#include "pipe/p_screen.h"
static void
-i915_draw_range_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned min_index,
- unsigned max_index,
- unsigned prim, unsigned start, unsigned count)
+i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
+ void *mapped_indices = NULL;
unsigned i;
if (i915->dirty)
/*
* Map index buffer, if present
*/
- if (indexBuffer) {
- void *mapped_indexes = i915_buffer(indexBuffer)->data;
- draw_set_mapped_element_buffer_range(draw, indexSize, indexBias,
- min_index,
- max_index,
- mapped_indexes);
- } else {
- draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+ if (info->indexed && i915->index_buffer.buffer) {
+ mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
+ mapped_indices += i915->index_buffer.offset;
}
+ draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+ i915->index_buffer.index_size : 0,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ mapped_indices);
+
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
i915->current.constants[PIPE_SHADER_VERTEX],
/*
* Do the drawing
*/
- draw_arrays(i915->draw, prim, start, count);
+ draw_arrays(i915->draw, info->mode, info->start, info->count);
/*
* unmap vertex/index buffers
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
- if (indexBuffer) {
+ if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}
+static void
+i915_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_resource *indexBuffer,
+ unsigned indexSize,
+ int indexBias,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned prim, unsigned start, unsigned count)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = prim;
+ info.start = start;
+ info.count = count;
+ info.index_bias = indexBias;
+ info.min_index = min_index;
+ info.max_index = max_index;
+
+ if (indexBuffer) {
+ info.indexed = TRUE;
+ saved_ib = i915->index_buffer;
+
+ ib.buffer = indexBuffer;
+ ib.offset = 0;
+ ib.index_size = indexSize;
+ pipe->set_index_buffer(pipe, &ib);
+ }
+
+ i915_draw_vbo(pipe, &info);
+
+ if (indexBuffer)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
+
static void
i915_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
i915->base.draw_arrays = i915_draw_arrays;
i915->base.draw_elements = i915_draw_elements;
i915->base.draw_range_elements = i915_draw_range_elements;
+ i915->base.draw_vbo = i915_draw_vbo;
/*
* Create drawing context and plug our rendering stage into it.
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer index_buffer;
unsigned dirty;
FREE( velems );
}
+static void i915_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct i915_context *i915 = i915_context(pipe);
+
+ if (ib)
+ memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer));
+ else
+ memset(&i915->index_buffer, 0, sizeof(i915->index_buffer));
+
+ /* TODO make this more like a state */
+}
+
static void
i915_set_sample_mask(struct pipe_context *pipe,
unsigned sample_mask)
i915->base.sampler_view_destroy = i915_sampler_view_destroy;
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
+ i915->base.set_index_buffer = i915_set_index_buffer;
}
*/
struct pipe_resource *index_buffer;
unsigned index_size;
+ unsigned index_offset;
/* Updates are signalled by PIPE_NEW_INDEX_RANGE:
*/
#include "util/u_inlines.h"
#include "util/u_prim.h"
#include "util/u_upload_mgr.h"
+#include "util/u_draw_quad.h"
#include "brw_draw.h"
#include "brw_defines.h"
*/
static int
try_draw_range_elements(struct brw_context *brw,
- struct pipe_resource *index_buffer,
+ boolean indexed,
unsigned hw_prim,
unsigned start, unsigned count)
{
if (ret)
return ret;
- ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim);
+ ret = brw_emit_prim(brw, start, count, indexed, hw_prim);
if (ret)
return ret;
static void
-brw_draw_range_elements(struct pipe_context *pipe,
- struct pipe_resource *index_buffer,
- unsigned index_size, int index_bias,
- unsigned min_index,
- unsigned max_index,
- unsigned mode, unsigned start, unsigned count)
+brw_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct brw_context *brw = brw_context(pipe);
int ret;
uint32_t hw_prim;
- hw_prim = brw_set_prim(brw, mode);
+ hw_prim = brw_set_prim(brw, info->mode);
if (BRW_DEBUG & DEBUG_PRIMS)
debug_printf("PRIM: %s start %d count %d index_buffer %p\n",
- u_prim_name(mode), start, count, (void *)index_buffer);
-
- assert(index_bias == 0);
+ u_prim_name(info->mode), info->start, info->count,
+ (void *) brw->curr.index_buffer);
- /* Potentially trigger upload of new index buffer.
- *
- * XXX: do we need to go through state validation to achieve this?
- * Could just call upload code directly.
- */
- if (brw->curr.index_buffer != index_buffer ||
- brw->curr.index_size != index_size) {
- pipe_resource_reference( &brw->curr.index_buffer, index_buffer );
- brw->curr.index_size = index_size;
- brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
- }
+ assert(info->index_bias == 0);
- /* XXX: do we really care?
+ /* Potentially trigger upload of new index buffer range.
+ * XXX: do we really care?
*/
- if (brw->curr.min_index != min_index ||
- brw->curr.max_index != max_index)
+ if (brw->curr.min_index != info->min_index ||
+ brw->curr.max_index != info->max_index)
{
- brw->curr.min_index = min_index;
- brw->curr.max_index = max_index;
+ brw->curr.min_index = info->min_index;
+ brw->curr.max_index = info->max_index;
brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE;
}
/* Make a first attempt at drawing:
*/
- ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
+ ret = try_draw_range_elements(brw, info->indexed,
+ hw_prim, info->start, info->count);
/* Otherwise, flush and retry:
*/
if (ret != 0) {
brw_context_flush( brw );
- ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
+ ret = try_draw_range_elements(brw, info->indexed,
+ hw_prim, info->start, info->count);
assert(ret == 0);
}
}
+static void
+brw_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_resource *index_buffer,
+ unsigned index_size, int index_bias,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned mode, unsigned start, unsigned count)
+{
+ struct brw_context *brw = brw_context(pipe);
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.index_bias = index_bias;
+ info.min_index = min_index;
+ info.max_index = max_index;
+
+ if (index_buffer) {
+ info.indexed = TRUE;
+ saved_ib.buffer = brw->curr.index_buffer;
+ saved_ib.offset = brw->curr.index_offset;
+ saved_ib.index_size = brw->curr.index_size;
+
+ ib.buffer = index_buffer;
+ ib.offset = 0;
+ ib.index_size = index_size;
+ pipe->set_index_buffer(pipe, &ib);
+ }
+
+ brw_draw_vbo(pipe, &info);
+
+ if (index_buffer)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
+
static void
brw_draw_elements(struct pipe_context *pipe,
struct pipe_resource *index_buffer,
brw->base.draw_arrays = brw_draw_arrays;
brw->base.draw_elements = brw_draw_elements;
brw->base.draw_range_elements = brw_draw_range_elements;
+ brw->base.draw_vbo = brw_draw_vbo;
/* Create helpers for uploading data in user buffers:
*/
struct pipe_resource *upload_buf = NULL;
struct brw_winsys_buffer *bo = NULL;
GLuint offset;
- GLuint index_size;
+ GLuint index_size, index_offset;
GLuint ib_size;
int ret;
ib_size = index_buffer->width0;
index_size = brw->curr.index_size;
+ index_offset = brw->curr.index_offset;
/* Turn userbuffer into a proper hardware buffer?
*/
if (brw_buffer_is_user_buffer(index_buffer)) {
ret = u_upload_buffer( brw->vb.upload_index,
- 0,
+ index_offset,
ib_size,
index_buffer,
&offset,
else {
bo = brw_buffer(index_buffer)->bo;
ib_size = bo->size;
- offset = 0;
+ offset = index_offset;
}
/* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the
}
+static void brw_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct brw_context *brw = brw_context(pipe);
+
+ if (ib) {
+ if (brw->curr.index_buffer == ib->buffer &&
+ brw->curr.index_offset == ib->offset &&
+ brw->curr.index_size == ib->index_size)
+ return;
+
+ pipe_resource_reference(&brw->curr.index_buffer, ib->buffer);
+ brw->curr.index_offset = ib->offset;
+ brw->curr.index_size = ib->index_size;
+ }
+ else {
+ if (!brw->curr.index_buffer &&
+ !brw->curr.index_offset &&
+ !brw->curr.index_size)
+ return;
+
+ pipe_resource_reference(&brw->curr.index_buffer, NULL);
+ brw->curr.index_offset = 0;
+ brw->curr.index_size = 0;
+ }
+
+ brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
+}
+
+
void
brw_pipe_vertex_init( struct brw_context *brw )
{
brw->base.set_vertex_buffers = brw_set_vertex_buffers;
+ brw->base.set_index_buffer = brw_set_index_buffer;
brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
count);
}
+static void
+identity_draw_vbo(struct pipe_context *_pipe,
+ const struct pipe_draw_info *info)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->draw_vbo(pipe, info);
+}
+
static struct pipe_query *
identity_create_query(struct pipe_context *_pipe,
unsigned query_type)
num_buffers,
buffers);
}
+
+static void
+identity_set_index_buffer(struct pipe_context *_pipe,
+ const struct pipe_index_buffer *_ib)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+ struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+ if (_ib) {
+ unwrapped_ib = *_ib;
+ unwrapped_ib.buffer = identity_resource_unwrap(_ib->buffer);
+ ib = &unwrapped_ib;
+ }
+
+ pipe->set_index_buffer(pipe, ib);
+}
+
static void
identity_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *_dst,
id_pipe->base.draw_arrays = identity_draw_arrays;
id_pipe->base.draw_elements = identity_draw_elements;
id_pipe->base.draw_range_elements = identity_draw_range_elements;
+ id_pipe->base.draw_vbo = identity_draw_vbo;
id_pipe->base.create_query = identity_create_query;
id_pipe->base.destroy_query = identity_destroy_query;
id_pipe->base.begin_query = identity_begin_query;
id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views;
id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
+ id_pipe->base.set_index_buffer = identity_set_index_buffer;
id_pipe->base.resource_copy_region = identity_resource_copy_region;
id_pipe->base.clear = identity_clear;
id_pipe->base.clear_render_target = identity_clear_render_target;
struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer index_buffer;
struct {
struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
int offset[PIPE_MAX_SO_BUFFERS];
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "util/u_prim.h"
+#include "util/u_draw_quad.h"
#include "lp_context.h"
#include "lp_state.h"
* the drawing to the 'draw' module.
*/
static void
-llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount)
+llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct llvmpipe_context *lp = llvmpipe_context(pipe);
struct draw_context *draw = lp->draw;
+ void *mapped_indices = NULL;
unsigned i;
if (lp->dirty)
}
/* Map index buffer, if present */
- if (indexBuffer) {
- void *mapped_indexes = llvmpipe_resource_data(indexBuffer);
- draw_set_mapped_element_buffer_range(draw,
- indexSize,
- indexBias,
- minIndex,
- maxIndex,
- mapped_indexes);
- }
- else {
- /* no index/element buffer */
- draw_set_mapped_element_buffer_range(draw, 0, 0, start,
- start + count - 1, NULL);
+ if (info->indexed && lp->index_buffer.buffer) {
+ mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer);
+ mapped_indices += lp->index_buffer.offset;
}
+
+ draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+ lp->index_buffer.index_size : 0,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ mapped_indices);
+
llvmpipe_prepare_vertex_sampling(lp,
lp->num_vertex_sampler_views,
lp->vertex_sampler_views);
/* draw! */
- draw_arrays_instanced(draw, mode, start, count,
- startInstance, instanceCount);
+ draw_arrays_instanced(draw, info->mode, info->start, info->count,
+ info->start_instance, info->instance_count);
/*
* unmap vertex/index buffers
for (i = 0; i < lp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
- if (indexBuffer) {
+ if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
llvmpipe_cleanup_vertex_sampling(lp);
}
+static void
+llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
+ struct pipe_resource *indexBuffer,
+ unsigned indexSize,
+ int indexBias,
+ unsigned minIndex,
+ unsigned maxIndex,
+ unsigned mode,
+ unsigned start,
+ unsigned count,
+ unsigned startInstance,
+ unsigned instanceCount)
+{
+ struct llvmpipe_context *lp = llvmpipe_context(pipe);
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.start_instance = startInstance;
+ info.instance_count = instanceCount;
+
+ info.index_bias = indexBias;
+ info.min_index = minIndex;
+ info.max_index = maxIndex;
+
+ if (indexBuffer) {
+ info.indexed = TRUE;
+ saved_ib = lp->index_buffer;
+
+ ib.buffer = indexBuffer;
+ ib.offset = 0;
+ ib.index_size = indexSize;
+ pipe->set_index_buffer(pipe, &ib);
+ }
+
+ llvmpipe_draw_vbo(pipe, &info);
+
+ if (indexBuffer)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
+
static void
llvmpipe_draw_arrays_instanced(struct pipe_context *pipe,
unsigned mode,
llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
llvmpipe->pipe.draw_arrays_instanced = llvmpipe_draw_arrays_instanced;
llvmpipe->pipe.draw_elements_instanced = llvmpipe_draw_elements_instanced;
+
+ llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo;
}
}
+static void
+llvmpipe_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ if (ib)
+ memcpy(&llvmpipe->index_buffer, ib, sizeof(llvmpipe->index_buffer));
+ else
+ memset(&llvmpipe->index_buffer, 0, sizeof(llvmpipe->index_buffer));
+
+ /* TODO make this more like a state */
+}
void
llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
+ llvmpipe->pipe.set_index_buffer = llvmpipe_set_index_buffer;
}
nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced;
nv50->pipe.draw_elements = nv50_draw_elements;
nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced;
+ nv50->pipe.draw_vbo = nv50_draw_vbo;
nv50->pipe.clear = nv50_clear;
nv50->pipe.flush = nv50_flush;
struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
+ struct pipe_index_buffer idxbuf;
struct nv50_vtxelt_stateobj *vtxelt;
struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS];
unsigned sampler_nr[3];
unsigned count,
unsigned startInstance,
unsigned instanceCount);
+extern void nv50_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
nv50->dirty |= NV50_NEW_ARRAYS;
}
+static void
+nv50_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+
+ if (ib)
+ memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+ else
+ memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf));
+
+ /* TODO make this more like a state */
+}
+
static void *
nv50_vtxelts_state_create(struct pipe_context *pipe,
unsigned num_elements,
nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
+ nv50->pipe.set_index_buffer = nv50_set_index_buffer;
}
mode, start, count, 0, 1);
}
+void
+nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+
+ if (info->indexed && nv50->idxbuf.buffer) {
+ unsigned offset;
+
+ assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0);
+ offset = nv50->idxbuf.offset / nv50->idxbuf.index_size;
+
+ nv50_draw_elements_instanced(pipe,
+ nv50->idxbuf.buffer,
+ nv50->idxbuf.index_size,
+ info->index_bias,
+ info->mode,
+ info->start + offset,
+ info->count,
+ info->start_instance,
+ info->instance_count);
+ }
+ else {
+ nv50_draw_arrays_instanced(pipe,
+ info->mode,
+ info->start,
+ info->count,
+ info->start_instance,
+ info->instance_count);
+ }
+}
+
static INLINE boolean
nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
struct nouveau_stateobj **pso,
nvfx->pipe.destroy = nvfx_destroy;
nvfx->pipe.draw_arrays = nvfx_draw_arrays;
nvfx->pipe.draw_elements = nvfx_draw_elements;
+ nvfx->pipe.draw_vbo = nvfx_draw_vbo;
nvfx->pipe.clear = nvfx_clear;
nvfx->pipe.flush = nvfx_flush;
struct pipe_stencil_ref stencil_ref;
struct pipe_viewport_state viewport;
struct pipe_framebuffer_state framebuffer;
- struct pipe_resource *idxbuf;
+ struct pipe_index_buffer idxbuf;
+ struct pipe_resource *idxbuf_buffer;
unsigned idxbuf_format;
struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
unsigned indexSize, int indexBias,
unsigned mode, unsigned start,
unsigned count);
+extern void nvfx_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
/* nvfx_vertprog.c */
extern boolean nvfx_vertprog_validate(struct nvfx_context *nvfx);
nvfx->draw_dirty |= NVFX_NEW_ARRAYS;
}
+static void
+nvfx_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ if (ib)
+ memcpy(&nvfx->idxbuf, ib, sizeof(nvfx->idxbuf));
+ else
+ memset(&nvfx->idxbuf, 0, sizeof(nvfx->idxbuf));
+
+ /* TODO make this more like a state */
+}
+
static void *
nvfx_vtxelts_state_create(struct pipe_context *pipe,
unsigned num_elements,
nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind;
nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers;
+ nvfx->pipe.set_index_buffer = nvfx_set_index_buffer;
}
unsigned type;
if (!ib) {
- nvfx->idxbuf = NULL;
+ nvfx->idxbuf_buffer = NULL;
nvfx->idxbuf_format = 0xdeadbeef;
return FALSE;
}
return FALSE;
}
- if (ib != nvfx->idxbuf ||
+ if (ib != nvfx->idxbuf_buffer ||
type != nvfx->idxbuf_format) {
nvfx->dirty |= NVFX_NEW_ARRAYS;
- nvfx->idxbuf = ib;
+ nvfx->idxbuf_buffer = ib;
nvfx->idxbuf_format = type;
}
pipe->flush(pipe, 0, NULL);
}
+void
+nvfx_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ if (info->indexed && nvfx->idxbuf.buffer) {
+ unsigned offset;
+
+ assert(nvfx->idxbuf.offset % nvfx->idxbuf.index_size == 0);
+ offset = nvfx->idxbuf.offset / nvfx->idxbuf.index_size;
+
+ nvfx_draw_elements(pipe,
+ nvfx->idxbuf.buffer,
+ nvfx->idxbuf.index_size,
+ info->index_bias,
+ info->mode,
+ info->start + offset,
+ info->count);
+ }
+ else {
+ nvfx_draw_arrays(pipe,
+ info->mode,
+ info->start,
+ info->count);
+ }
+}
+
boolean
nvfx_vbo_validate(struct nvfx_context *nvfx)
{
struct nouveau_channel* chan = nvfx->screen->base.channel;
- struct pipe_resource *ib = nvfx->idxbuf;
+ struct pipe_resource *ib = nvfx->idxbuf_buffer;
unsigned ib_format = nvfx->idxbuf_format;
int i;
int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr);
}
}
- if(nvfx->idxbuf)
+ if(nvfx->idxbuf_buffer)
{
unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
- struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf)->bo;
+ struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf_buffer)->bo;
assert(nvfx->screen->index_buffer_reloc_flags);
struct r300_vertex_element_state *velems;
bool any_user_vbs;
+ struct pipe_index_buffer index_buffer;
+
/* Vertex info for Draw. */
struct vertex_info vertex_info;
#include "util/u_memory.h"
#include "util/u_upload_mgr.h"
#include "util/u_prim.h"
+#include "util/u_draw_quad.h"
#include "r300_cs.h"
#include "r300_context.h"
}
}
+static void r300_draw_vbo(struct pipe_context* pipe,
+ const struct pipe_draw_info *info)
+{
+ struct r300_context* r300 = r300_context(pipe);
+
+ if (info->indexed && r300->index_buffer.buffer) {
+ unsigned offset;
+
+ assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
+ offset = r300->index_buffer.offset / r300->index_buffer.index_size;
+
+ r300_draw_range_elements(pipe,
+ r300->index_buffer.buffer,
+ r300->index_buffer.index_size,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ info->mode,
+ info->start + offset,
+ info->count);
+ }
+ else {
+ r300_draw_arrays(pipe,
+ info->mode,
+ info->start,
+ info->count);
+ }
+}
+
/****************************************************************************
* The rest of this file is for SW TCL rendering only. Please be polite and *
* keep these functions separated so that they are easier to locate. ~C. *
***************************************************************************/
-/* SW TCL arrays, using Draw. */
-static void r300_swtcl_draw_arrays(struct pipe_context* pipe,
- unsigned mode,
- unsigned start,
- unsigned count)
+/* SW TCL elements, using Draw. */
+static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
+ const struct pipe_draw_info *info)
{
struct r300_context* r300 = r300_context(pipe);
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *ib_transfer;
+ unsigned count = info->count;
int i;
+ void* indices = NULL;
if (r300->skip_rendering) {
return;
}
- if (!u_trim_pipe_prim(mode, &count)) {
+ if (!u_trim_pipe_prim(info->mode, &count)) {
return;
}
void* buf = pipe_buffer_map(pipe,
r300->vertex_buffer[i].buffer,
PIPE_TRANSFER_READ,
- &vb_transfer[i]);
+ &vb_transfer[i]);
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
}
- draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL);
+ if (info->indexed && r300->index_buffer.buffer) {
+ indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
+ PIPE_TRANSFER_READ, &ib_transfer);
+ if (indices)
+ indices += r300->index_buffer.offset;
+ }
+
+ draw_set_mapped_element_buffer_range(r300->draw, (indices) ?
+ r300->index_buffer.index_size : 0,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ indices);
- draw_arrays(r300->draw, mode, start, count);
+ draw_arrays(r300->draw, info->mode, info->start, count);
/* XXX Not sure whether this is the best fix.
* It prevents CS from being rejected and weird assertion failures. */
for (i = 0; i < r300->vertex_buffer_count; i++) {
pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
- vb_transfer[i]);
+ vb_transfer[i]);
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
}
+
+ if (ib_transfer) {
+ pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer);
+ draw_set_mapped_element_buffer_range(r300->draw, 0, 0, info->start,
+ info->start + count - 1, NULL);
+ }
}
/* SW TCL elements, using Draw. */
unsigned count)
{
struct r300_context* r300 = r300_context(pipe);
- struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
- struct pipe_transfer *ib_transfer;
- int i;
- void* indices;
-
- if (r300->skip_rendering) {
- return;
- }
-
- if (!u_trim_pipe_prim(mode, &count)) {
- return;
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.index_bias = indexBias;
+ info.min_index = minIndex;
+ info.max_index = maxIndex;
+
+ if (indexBuffer) {
+ info.indexed = TRUE;
+
+ saved_ib = r300->index_buffer;
+ ib.buffer = indexBuffer;
+ ib.offset = 0;
+ ib.index_size = indexSize;
+ pipe->set_index_buffer(pipe, &ib);
}
- r300_update_derived_state(r300);
-
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- void* buf = pipe_buffer_map(pipe,
- r300->vertex_buffer[i].buffer,
- PIPE_TRANSFER_READ,
- &vb_transfer[i]);
- draw_set_mapped_vertex_buffer(r300->draw, i, buf);
- }
-
- indices = pipe_buffer_map(pipe, indexBuffer,
- PIPE_TRANSFER_READ, &ib_transfer);
- draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias,
- minIndex, maxIndex, indices);
-
- draw_arrays(r300->draw, mode, start, count);
-
- /* XXX Not sure whether this is the best fix.
- * It prevents CS from being rejected and weird assertion failures. */
- draw_flush(r300->draw);
+ r300_swtcl_draw_vbo(pipe, &info);
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
- vb_transfer[i]);
- draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
- }
+ if (indexBuffer)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
- pipe_buffer_unmap(pipe, indexBuffer,
- ib_transfer);
- draw_set_mapped_element_buffer_range(r300->draw, 0, 0,
- start, start + count - 1,
- NULL);
+static void r300_swtcl_draw_arrays(struct pipe_context* pipe,
+ unsigned mode,
+ unsigned start,
+ unsigned count)
+{
+ r300_swtcl_draw_range_elements(pipe, NULL, 0, 0,
+ start, start + count -1, mode, start, count);
}
/* Object for rendering using Draw. */
if (r300->screen->caps.has_tcl) {
r300->context.draw_arrays = r300_draw_arrays;
r300->context.draw_range_elements = r300_draw_range_elements;
+ r300->context.draw_vbo = r300_draw_vbo;
} else {
r300->context.draw_arrays = r300_swtcl_draw_arrays;
r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
+ r300->context.draw_vbo = r300_swtcl_draw_vbo;
}
r300->context.resource_resolve = r300_resource_resolve;
unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex,
unsigned mode, unsigned start, unsigned count);
+ void (*draw_vbo)(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
+
uint32_t rs_cull_mode;
uint32_t zb_stencilrefmask;
ubyte ref_value_front;
}
}
+static void r300_stencilref_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_stencilref_context *sr = r300->stencilref_fallback;
+
+ if (!r300_stencilref_needed(r300)) {
+ sr->draw_vbo(pipe, info);
+ } else {
+ r300_stencilref_begin(r300);
+ sr->draw_vbo(pipe, info);
+ r300_stencilref_switch_side(r300);
+ sr->draw_vbo(pipe, info);
+ r300_stencilref_end(r300);
+ }
+}
+
void r300_plug_in_stencil_ref_fallback(struct r300_context *r300)
{
r300->stencilref_fallback = CALLOC_STRUCT(r300_stencilref_context);
/* Save original draw functions. */
r300->stencilref_fallback->draw_arrays = r300->context.draw_arrays;
r300->stencilref_fallback->draw_range_elements = r300->context.draw_range_elements;
+ r300->stencilref_fallback->draw_vbo = r300->context.draw_vbo;
/* Override the draw functions. */
r300->context.draw_arrays = r300_stencilref_draw_arrays;
r300->context.draw_range_elements = r300_stencilref_draw_range_elements;
+ r300->context.draw_vbo = r300_stencilref_draw_vbo;
}
r300->vertex_buffer_count = count;
}
+static void r300_set_index_buffer(struct pipe_context* pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct r300_context* r300 = r300_context(pipe);
+
+ if (ib) {
+ pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer);
+ memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer));
+ }
+ else {
+ pipe_resource_reference(&r300->index_buffer.buffer, NULL);
+ memset(&r300->index_buffer, 0, sizeof(r300->index_buffer));
+ }
+
+ /* TODO make this more like a state */
+}
+
/* Initialize the PSC tables. */
static void r300_vertex_psc(struct r300_vertex_element_state *velems)
{
r300->context.set_viewport_state = r300_set_viewport_state;
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
+ r300->context.set_index_buffer = r300_set_index_buffer;
r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
rctx->context.draw_arrays = r600_draw_arrays;
rctx->context.draw_elements = r600_draw_elements;
rctx->context.draw_range_elements = r600_draw_range_elements;
+ rctx->context.draw_vbo = r600_draw_vbo;
rctx->context.flush = r600_flush;
/* Easy accessing of screen/winsys. */
struct r600_context_state *vs_sampler_view[PIPE_MAX_ATTRIBS];
struct r600_vertex_element *vertex_elements;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer index_buffer;
};
#if 0
unsigned index_size, int index_bias, unsigned min_index,
unsigned max_index, unsigned mode,
unsigned start, unsigned count);
+void r600_draw_vbo(struct pipe_context *ctx,
+ const struct pipe_draw_info *info);
void r600_init_blit_functions(struct r600_context *rctx);
void r600_init_state_functions(struct r600_context *rctx);
draw.index_buffer = NULL;
r600_draw_common(&draw);
}
+
+void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_draw draw;
+
+ assert(info->index_bias == 0);
+
+ draw.ctx = ctx;
+ draw.mode = info->mode;
+ draw.start = info->start;
+ draw.count = info->count;
+ if (info->indexed && rctx->index_buffer.buffer) {
+ draw.index_size = rctx->index_buffer.index_size;
+ draw.index_buffer = rctx->index_buffer.buffer;
+
+ assert(rctx->index_buffer.offset %
+ rctx->index_buffer.index_size == 0);
+ draw.start += rctx->index_buffer.offset /
+ rctx->index_buffer.index_size;
+ }
+ else {
+ draw.index_size = 0;
+ draw.index_buffer = NULL;
+ }
+ r600_draw_common(&draw);
+}
rctx->nvertex_buffer = count;
}
+static void r600_set_index_buffer(struct pipe_context *ctx,
+ const struct pipe_index_buffer *ib)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ if (ib) {
+ pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer);
+ memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer));
+ }
+ else {
+ pipe_resource_reference(&rctx->index_buffer.buffer, NULL);
+ memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer));
+ }
+
+ /* TODO make this more like a state */
+}
+
static void r600_set_viewport_state(struct pipe_context *ctx,
const struct pipe_viewport_state *state)
{
rctx->context.set_scissor_state = r600_set_scissor_state;
rctx->context.set_stencil_ref = r600_set_stencil_ref;
rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
+ rctx->context.set_index_buffer = r600_set_index_buffer;
rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_view;
rctx->context.set_viewport_state = r600_set_viewport_state;
rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
pipe_mutex_unlock(rb_pipe->draw_mutex);
}
+static void
+rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
+{
+ struct rbug_context *rb_pipe = rbug_context(_pipe);
+ struct pipe_context *pipe = rb_pipe->pipe;
+
+ pipe_mutex_lock(rb_pipe->draw_mutex);
+ rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE);
+
+ pipe->draw_vbo(pipe, info);
+
+ rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);
+ pipe_mutex_unlock(rb_pipe->draw_mutex);
+}
+
static struct pipe_query *
rbug_create_query(struct pipe_context *_pipe,
unsigned query_type)
buffers);
}
+static void
+rbug_set_index_buffer(struct pipe_context *_pipe,
+ const struct pipe_index_buffer *_ib)
+{
+ struct rbug_context *rb_pipe = rbug_context(_pipe);
+ struct pipe_context *pipe = rb_pipe->pipe;
+ struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+ if (_ib) {
+ unwrapped_ib = *_ib;
+ unwrapped_ib.buffer = rbug_resource_unwrap(_ib->buffer);
+ ib = &unwrapped_ib;
+ }
+
+ pipe->set_index_buffer(pipe, ib);
+}
+
static void
rbug_set_sample_mask(struct pipe_context *_pipe,
unsigned sample_mask)
rb_pipe->base.draw_arrays = rbug_draw_arrays;
rb_pipe->base.draw_elements = rbug_draw_elements;
rb_pipe->base.draw_range_elements = rbug_draw_range_elements;
+ rb_pipe->base.draw_vbo = rbug_draw_vbo;
rb_pipe->base.create_query = rbug_create_query;
rb_pipe->base.destroy_query = rbug_destroy_query;
rb_pipe->base.begin_query = rbug_begin_query;
rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views;
rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views;
rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
+ rb_pipe->base.set_index_buffer = rbug_set_index_buffer;
rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
rb_pipe->base.clear = rbug_clear;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_stream_output_buffers = softpipe_set_stream_output_buffers;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
+ softpipe->pipe.set_index_buffer = softpipe_set_index_buffer;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
softpipe->pipe.draw_range_elements = softpipe_draw_range_elements;
softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced;
softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced;
+ softpipe->pipe.draw_vbo = softpipe_draw_vbo;
softpipe->pipe.draw_stream_output = softpipe_draw_stream_output;
softpipe->pipe.clear = softpipe_clear;
struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer index_buffer;
struct {
struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
int offset[PIPE_MAX_SO_BUFFERS];
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#include "util/u_prim.h"
+#include "util/u_draw_quad.h"
#include "sp_context.h"
#include "sp_query.h"
* When the min/max element indexes aren't known, minIndex should be 0
* and maxIndex should be ~0.
*/
-static void
-softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount)
+void
+softpipe_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info)
{
struct softpipe_context *sp = softpipe_context(pipe);
struct draw_context *draw = sp->draw;
+ void *mapped_indices = NULL;
unsigned i;
if (!softpipe_check_render_cond(sp))
return;
- sp->reduced_api_prim = u_reduced_prim(mode);
+ sp->reduced_api_prim = u_reduced_prim(info->mode);
if (sp->dirty) {
softpipe_update_derived(sp);
}
/* Map index buffer, if present */
- if (indexBuffer) {
- void *mapped_indexes = softpipe_resource(indexBuffer)->data;
- draw_set_mapped_element_buffer_range(draw,
- indexSize,
- indexBias,
- minIndex,
- maxIndex,
- mapped_indexes);
- } else {
- /* no index/element buffer */
- draw_set_mapped_element_buffer_range(draw,
- 0, 0,
- start,
- start + count - 1,
- NULL);
+ if (info->indexed && sp->index_buffer.buffer) {
+ mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+ mapped_indices += sp->index_buffer.offset;
}
+ draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+ sp->index_buffer.index_size : 0,
+ info->index_bias,
+ info->min_index,
+ info->max_index,
+ mapped_indices);
+
/* draw! */
- draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount);
+ draw_arrays_instanced(draw, info->mode, info->start, info->count,
+ info->start_instance, info->instance_count);
/* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
- if (indexBuffer) {
+ if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
sp->dirty_render_cache = TRUE;
}
+static void
+softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
+ struct pipe_resource *indexBuffer,
+ unsigned indexSize,
+ int indexBias,
+ unsigned minIndex,
+ unsigned maxIndex,
+ unsigned mode,
+ unsigned start,
+ unsigned count,
+ unsigned startInstance,
+ unsigned instanceCount)
+{
+ struct softpipe_context *sp = softpipe_context(pipe);
+ struct pipe_draw_info info;
+ struct pipe_index_buffer saved_ib, ib;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.start_instance = startInstance;
+ info.instance_count = instanceCount;
+ info.index_bias = indexBias;
+ info.min_index = minIndex;
+ info.max_index = maxIndex;
+
+ if (indexBuffer) {
+ info.indexed = TRUE;
+
+ saved_ib = sp->index_buffer;
+ ib.buffer = indexBuffer;
+ ib.offset = 0;
+ ib.index_size = indexSize;
+ pipe->set_index_buffer(pipe, &ib);
+ }
+
+ softpipe_draw_vbo(pipe, &info);
+
+ if (indexBuffer)
+ pipe->set_index_buffer(pipe, &saved_ib);
+}
+
void
softpipe_draw_range_elements(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_buffer *);
+void softpipe_set_index_buffer(struct pipe_context *,
+ const struct pipe_index_buffer *);
+
void softpipe_update_derived( struct softpipe_context *softpipe );
unsigned startInstance,
unsigned instanceCount);
+void
+softpipe_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
+
void softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode);
void
draw_set_vertex_buffers(softpipe->draw, count, buffers);
}
+
+void
+softpipe_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+
+ if (ib)
+ memcpy(&softpipe->index_buffer, ib, sizeof(softpipe->index_buffer));
+ else
+ memset(&softpipe->index_buffer, 0, sizeof(softpipe->index_buffer));
+
+ /* TODO make this more like a state */
+}
struct svga_vertex_shader *vs;
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer ib;
struct pipe_resource *cb[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
start, count);
}
+static void
+svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+ struct svga_context *svga = svga_context(pipe);
+
+ if (info->indexed && svga->curr.ib.buffer) {
+ unsigned offset;
+
+ assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0);
+ offset = svga->curr.ib.offset / svga->curr.ib.index_size;
+
+ svga_draw_range_elements(pipe, svga->curr.ib.buffer,
+ svga->curr.ib.index_size, info->index_bias,
+ info->min_index, info->max_index,
+ info->mode, info->start + offset, info->count);
+ }
+ else {
+ svga_draw_range_elements(pipe, NULL, 0, 0,
+ info->min_index, info->max_index,
+ info->mode, info->start, info->count);
+ }
+}
+
void svga_init_draw_functions( struct svga_context *svga )
{
svga->pipe.draw_arrays = svga_draw_arrays;
svga->pipe.draw_elements = svga_draw_elements;
svga->pipe.draw_range_elements = svga_draw_range_elements;
+ svga->pipe.draw_vbo = svga_draw_vbo;
}
}
+static void svga_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct svga_context *svga = svga_context(pipe);
+
+ if (ib) {
+ pipe_resource_reference(&svga->curr.ib.buffer, ib->buffer);
+ memcpy(&svga->curr.ib, ib, sizeof(svga->curr.ib));
+ }
+ else {
+ pipe_resource_reference(&svga->curr.ib.buffer, NULL);
+ memset(&svga->curr.ib, 0, sizeof(svga->curr.ib));
+ }
+
+ /* TODO make this more like a state */
+}
+
+
static void *
svga_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
void svga_init_vertex_functions( struct svga_context *svga )
{
svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
+ svga->pipe.set_index_buffer = svga_set_index_buffer;
svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
}
+static INLINE void
+trace_context_draw_vbo(struct pipe_context *_pipe,
+ const struct pipe_draw_info *info)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "draw_vbo");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(bool, info->indexed);
+ trace_dump_arg(uint, info->mode);
+ trace_dump_arg(uint, info->start);
+ trace_dump_arg(uint, info->count);
+ trace_dump_arg(uint, info->start_instance);
+ trace_dump_arg(uint, info->instance_count);
+ trace_dump_arg(int, info->index_bias);
+ trace_dump_arg(uint, info->min_index);
+ trace_dump_arg(uint, info->max_index);
+
+ pipe->draw_vbo(pipe, info);
+
+ trace_dump_call_end();
+}
+
+
static INLINE struct pipe_query *
trace_context_create_query(struct pipe_context *_pipe,
unsigned query_type)
}
+static INLINE void
+trace_context_set_index_buffer(struct pipe_context *_pipe,
+ const struct pipe_index_buffer *_ib)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+ if (_ib) {
+ unwrapped_ib = *_ib;
+ unwrapped_ib.buffer = trace_resource_unwrap(tr_ctx, _ib->buffer);
+ ib = &unwrapped_ib;
+ }
+
+ trace_dump_call_begin("pipe_context", "set_index_buffer");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(index_buffer, ib);
+
+ pipe->set_index_buffer(pipe, ib);
+
+ trace_dump_call_end();
+}
+
static INLINE void
trace_context_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *dst,
tr_ctx->base.draw_arrays = trace_context_draw_arrays;
tr_ctx->base.draw_elements = trace_context_draw_elements;
tr_ctx->base.draw_range_elements = trace_context_draw_range_elements;
+ tr_ctx->base.draw_vbo = trace_context_draw_vbo;
tr_ctx->base.create_query = trace_context_create_query;
tr_ctx->base.destroy_query = trace_context_destroy_query;
tr_ctx->base.begin_query = trace_context_begin_query;
tr_ctx->base.create_sampler_view = trace_create_sampler_view;
tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
+ tr_ctx->base.set_index_buffer = trace_context_set_index_buffer;
tr_ctx->base.resource_copy_region = trace_context_resource_copy_region;
tr_ctx->base.clear = trace_context_clear;
tr_ctx->base.clear_render_target = trace_context_clear_render_target;
}
+void trace_dump_index_buffer(const struct pipe_index_buffer *state)
+{
+ if (!trace_dumping_enabled_locked())
+ return;
+
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_index_buffer");
+
+ trace_dump_member(uint, state, index_size);
+ trace_dump_member(uint, state, offset);
+ trace_dump_member(resource_ptr, state, buffer);
+
+ trace_dump_struct_end();
+}
+
+
void trace_dump_vertex_element(const struct pipe_vertex_element *state)
{
if (!trace_dumping_enabled_locked())
void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state);
+void trace_dump_index_buffer(const struct pipe_index_buffer *state);
+
void trace_dump_vertex_element(const struct pipe_vertex_element *state);