static void finalize_index_buffer(struct ilo_context *ilo) { struct ilo_state_vector *vec = &ilo->state_vector; const bool need_upload = (vec->draw->indexed && (vec->ib.user_buffer || vec->ib.offset % vec->ib.index_size)); struct pipe_resource *current_hw_res = NULL; if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload) return; pipe_resource_reference(¤t_hw_res, vec->ib.hw_resource); if (need_upload) { const unsigned offset = vec->ib.index_size * vec->draw->start; const unsigned size = vec->ib.index_size * vec->draw->count; unsigned hw_offset; if (vec->ib.user_buffer) { u_upload_data(ilo->uploader, 0, size, vec->ib.user_buffer + offset, &hw_offset, &vec->ib.hw_resource); } else { u_upload_buffer(ilo->uploader, 0, vec->ib.offset + offset, size, vec->ib.buffer, &hw_offset, &vec->ib.hw_resource); } /* the HW offset should be aligned */ assert(hw_offset % vec->ib.index_size == 0); vec->ib.draw_start_offset = hw_offset / vec->ib.index_size; /* * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW * resource */ vec->ib.draw_start_offset -= vec->draw->start; } else { pipe_resource_reference(&vec->ib.hw_resource, vec->ib.buffer); /* note that index size may be zero when the draw is not indexed */ if (vec->draw->indexed) vec->ib.draw_start_offset = vec->ib.offset / vec->ib.index_size; else vec->ib.draw_start_offset = 0; } /* treat the IB as clean if the HW states do not change */ if (vec->ib.hw_resource == current_hw_res && vec->ib.hw_index_size == vec->ib.index_size) vec->dirty &= ~ILO_DIRTY_IB; else vec->ib.hw_index_size = vec->ib.index_size; pipe_resource_reference(¤t_hw_res, NULL); }
static int svga_upload_user_buffers(struct svga_context *svga, unsigned start, unsigned count, unsigned instance_count) { const struct pipe_vertex_element *ve = svga->curr.velems->velem; unsigned i; int ret; svga_user_buffer_range(svga, start, count, instance_count); for (i=0; i < svga->curr.velems->count; i++) { struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { struct svga_buffer *buffer = svga_buffer(vb->buffer); /* * Check if already uploaded. Otherwise go ahead and upload. */ if (buffer->uploaded.buffer) continue; ret = u_upload_buffer( svga->upload_vb, 0, buffer->uploaded.start, buffer->uploaded.end - buffer->uploaded.start, &buffer->b.b, &buffer->uploaded.offset, &buffer->uploaded.buffer); if (ret) return ret; if (0) debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sofs %d" " sz %d\n", __FUNCTION__, i, buffer, buffer->uploaded.buffer, buffer->uploaded.offset, buffer->uploaded.start, buffer->uploaded.end - buffer->uploaded.start); vb->buffer_offset = buffer->uploaded.offset; } } return PIPE_OK; }
static int upload_user_buffers( struct svga_context *svga ) { enum pipe_error ret = PIPE_OK; int i; int nr; if (0) debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers); nr = svga->curr.num_vertex_buffers; for (i = 0; i < nr; i++) { if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer)) { struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer); if (!buffer->uploaded.buffer) { ret = u_upload_buffer( svga->upload_vb, 0, buffer->base.size, &buffer->base, &buffer->uploaded.offset, &buffer->uploaded.buffer ); if (ret) return ret; if (0) debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", __FUNCTION__, i, buffer, buffer->uploaded.buffer, buffer->uploaded.offset, buffer->base.size); } pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer ); svga->curr.vb[i].buffer_offset = buffer->uploaded.offset; } } if (0) debug_printf("%s: DONE\n", __FUNCTION__); return ret; }
enum pipe_error svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, struct pipe_resource *index_buffer, unsigned index_size, int index_bias, unsigned min_index, unsigned max_index, unsigned prim, unsigned start, unsigned count ) { struct pipe_resource *upload_buffer = NULL; SVGA3dPrimitiveRange range; unsigned hw_prim; unsigned hw_count; unsigned index_offset = start * index_size; enum pipe_error ret = PIPE_OK; hw_prim = svga_translate_prim(prim, count, &hw_count); if (hw_count == 0) goto done; if (index_buffer && svga_buffer_is_user_buffer(index_buffer)) { assert( index_buffer->width0 >= index_offset + count * index_size ); ret = u_upload_buffer( hwtnl->upload_ib, 0, index_offset, count * index_size, index_buffer, &index_offset, &upload_buffer); if (ret != PIPE_OK) goto done; /* Don't need to worry about refcounting index_buffer as this is * just a stack variable without a counted reference of its own. * The caller holds the reference. */ index_buffer = upload_buffer; } range.primType = hw_prim; range.primitiveCount = hw_count; range.indexArray.offset = index_offset; range.indexArray.stride = index_size; range.indexWidth = index_size; range.indexBias = index_bias; ret = svga_hwtnl_prim( hwtnl, &range, min_index, max_index, index_buffer ); if (ret != PIPE_OK) goto done; done: if (upload_buffer) pipe_resource_reference( &upload_buffer, NULL ); return ret; }