static void 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; const void *mapped_indices = NULL; /* * Ack vs contants here, helps ipers a lot. */ i915->dirty &= ~I915_NEW_VS_CONSTANTS; if (i915->dirty) i915_update_derived(i915); /* * Map index buffer, if present */ if (info->indexed) { mapped_indices = i915->index_buffer.user_buffer; if (!mapped_indices) mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; draw_set_indexes(draw, (ubyte *) mapped_indices + i915->index_buffer.offset, i915->index_buffer.index_size); } if (i915->constants[PIPE_SHADER_VERTEX]) draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 * sizeof(float))); else draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); if (i915->num_vertex_sampler_views > 0) i915_prepare_vertex_sampling(i915); /* * Do the drawing */ draw_vbo(i915->draw, info); if (mapped_indices) draw_set_indexes(draw, NULL, 0); if (i915->num_vertex_sampler_views > 0) i915_cleanup_vertex_sampling(i915); /* * Instead of flushing on every state change, we flush once here * when we fire the vbo. */ draw_flush(i915->draw); }
static void i915_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_constant_buffer *cb) { struct i915_context *i915 = i915_context(pipe); struct pipe_resource *buf = cb ? cb->buffer : NULL; unsigned new_num = 0; boolean diff = TRUE; /* XXX don't support geom shaders now */ if (shader == PIPE_SHADER_GEOMETRY) return; if (cb && cb->user_buffer) { buf = i915_user_buffer_create(pipe->screen, (void *) cb->user_buffer, cb->buffer_size, PIPE_BIND_CONSTANT_BUFFER); } /* if we have a new buffer compare it with the old one */ if (buf) { struct i915_buffer *ibuf = i915_buffer(buf); struct pipe_resource *old_buf = i915->constants[shader]; struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL; unsigned old_num = i915->current.num_user_constants[shader]; new_num = ibuf->b.b.width0 / 4 * sizeof(float); if (old_num == new_num) { if (old_num == 0) diff = FALSE; #if 0 /* XXX no point in running this code since st/mesa only uses user buffers */ /* Can't compare the buffer data since they are userbuffers */ else if (old && old->free_on_destroy) diff = memcmp(old->data, ibuf->data, ibuf->b.b.width0); #else (void)old; #endif } } else { diff = i915->current.num_user_constants[shader] != 0; } pipe_resource_reference(&i915->constants[shader], buf); i915->current.num_user_constants[shader] = new_num; if (diff) i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; if (cb && cb->user_buffer) { pipe_resource_reference(&buf, NULL); } }
static void * i915_buffer_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) { struct i915_buffer *buffer = i915_buffer(transfer->resource); return buffer->data + transfer->box.x; }
static void i915_set_vertex_buffers(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; int i; util_copy_vertex_buffers(i915->saved_vertex_buffers, &i915->saved_nr_vertex_buffers, buffers, count); #if 0 /* XXX doesn't look like this is needed */ /* unmap old */ for (i = 0; i < i915->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } #endif /* pass-through to draw module */ draw_set_vertex_buffers(draw, count, buffers); /* map new */ for (i = 0; i < count; i++) { void *buf = i915_buffer(buffers[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } }
static void i915_buffer_unmap(struct pipe_screen *screen, struct pipe_buffer *buffer) { struct i915_buffer *buf = i915_buffer(buffer); assert(!buf->ibuf); }
static void i915_buffer_destroy(struct pipe_screen *screen, struct pipe_resource *resource) { struct i915_buffer *buffer = i915_buffer(resource); if (buffer->free_on_destroy) align_free(buffer->data); FREE(buffer); }
static void * i915_buffer_map(struct pipe_screen *screen, struct pipe_buffer *buffer, unsigned usage) { struct i915_buffer *buf = i915_buffer(buffer); assert(!buf->ibuf); return buf->data; }
static void i915_buffer_destroy(struct pipe_buffer *buffer) { struct i915_buffer *buf = i915_buffer(buffer); assert(!buf->ibuf); if (buf->own) FREE(buf->data); FREE(buf); }
static void i915_buffer_transfer_inline_write( struct pipe_context *rm_ctx, struct pipe_resource *resource, unsigned level, unsigned usage, const struct pipe_box *box, const void *data, unsigned stride, unsigned layer_stride) { struct i915_buffer *buffer = i915_buffer(resource); memcpy(buffer->data + box->x, data, box->width); }
static void * i915_buffer_transfer_map(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, unsigned usage, const struct pipe_box *box, struct pipe_transfer **ptransfer) { struct i915_context *i915 = i915_context(pipe); struct i915_buffer *buffer = i915_buffer(resource); struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); if (transfer == NULL) return NULL; transfer->resource = resource; transfer->level = level; transfer->usage = usage; transfer->box = *box; *ptransfer = transfer; return buffer->data + transfer->box.x; }