/* u_vbuf uses its own caching for vertex elements, because it needs to keep * its own preprocessed state per vertex element CSO. */ static struct u_vbuf_elements * u_vbuf_set_vertex_elements_internal(struct u_vbuf *mgr, unsigned count, const struct pipe_vertex_element *states) { struct pipe_context *pipe = mgr->pipe; unsigned key_size, hash_key; struct cso_hash_iter iter; struct u_vbuf_elements *ve; struct cso_velems_state velems_state; /* need to include the count into the stored state data too. */ key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned); velems_state.count = count; memcpy(velems_state.velems, states, sizeof(struct pipe_vertex_element) * count); hash_key = cso_construct_key((void*)&velems_state, key_size); iter = cso_find_state_template(mgr->cso_cache, hash_key, CSO_VELEMENTS, (void*)&velems_state, key_size); if (cso_hash_iter_is_null(iter)) { struct cso_velements *cso = MALLOC_STRUCT(cso_velements); memcpy(&cso->state, &velems_state, key_size); cso->data = u_vbuf_create_vertex_elements(mgr, count, states); cso->delete_state = (cso_state_callback)u_vbuf_delete_vertex_elements; cso->context = (void*)mgr; iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso); ve = cso->data; } else { ve = ((struct cso_velements *)cso_hash_iter_data(iter))->data; } assert(ve); if (ve != mgr->ve) pipe->bind_vertex_elements_state(pipe, ve->driver_cso); return ve; }
void *r600_create_vertex_elements(struct pipe_context *ctx, unsigned count, const struct pipe_vertex_element *elements) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); assert(count < 32); if (!v) return NULL; v->count = count; v->vmgr_elements = u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count, elements, v->elements); if (r600_vertex_elements_build_fetch_shader(rctx, v)) { FREE(v); return NULL; } return v; }