void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_buffer *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); unsigned size = constants ? constants->size : 0; const void *data = constants ? llvmpipe_buffer(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); if(llvmpipe->constants[shader] == constants) return; draw_flush(llvmpipe->draw); /* note: reference counting */ pipe_buffer_reference(&llvmpipe->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, data, size); } llvmpipe->dirty |= LP_NEW_CONSTANTS; }
void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); struct pipe_buffer *buffer = constants ? constants->buffer : NULL; unsigned size = buffer ? buffer->size : 0; const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); if(shader == PIPE_SHADER_VERTEX) draw_flush(llvmpipe->draw); /* note: reference counting */ pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer); if(shader == PIPE_SHADER_FRAGMENT) { llvmpipe->jit_context.constants = data; } if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, data, size); } llvmpipe->dirty |= LP_NEW_CONSTANTS; }
/** * Draw vertex arrays, with optional indexing. * Basically, map the vertex buffers (and drawing surfaces), then hand off * the drawing to the 'draw' module. */ boolean llvmpipe_draw_range_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, unsigned mode, unsigned start, unsigned count) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; unsigned i; lp->reduced_api_prim = u_reduced_prim(mode); if (lp->dirty) llvmpipe_update_derived( lp ); llvmpipe_map_transfers(lp); /* * Map vertex buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { void *buf = llvmpipe_buffer(lp->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { void *mapped_indexes = llvmpipe_buffer(indexBuffer)->data; draw_set_mapped_element_buffer_range(draw, indexSize, min_index, max_index, mapped_indexes); } else { /* no index/element buffer */ draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); } /* draw! */ draw_arrays(draw, mode, start, count); /* * unmap vertex/index buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } if (indexBuffer) { draw_set_mapped_element_buffer(draw, 0, NULL); } /* * TODO: Flush only when a user vertex/index buffer is present * (or even better, modify draw module to do this * internally when this condition is seen?) */ draw_flush(draw); /* Note: leave drawing surfaces mapped */ lp->dirty_render_cache = TRUE; return TRUE; }