- struct drm_radeon_cs_reloc *reloc;
- unsigned i;
- unsigned hash = bo->handle & (sizeof(csc->is_handle_added)-1);
-
- if (csc->is_handle_added[hash]) {
- reloc = csc->relocs_hashlist[hash];
- if (reloc->handle == bo->handle) {
- return csc->reloc_indices_hashlist[hash];
- }
-
- /* Hash collision, look for the BO in the list of relocs linearly. */
- for (i = csc->crelocs; i != 0;) {
- --i;
- reloc = &csc->relocs[i];
- if (reloc->handle == bo->handle) {
- /* Put this reloc in the hash list.
- * This will prevent additional hash collisions if there are
- * several subsequent get_reloc calls of the same buffer.
- *
- * Example: Assuming buffers A,B,C collide in the hash list,
- * the following sequence of relocs:
- * AAAAAAAAAAABBBBBBBBBBBBBBCCCCCCCC
- * will collide here: ^ and here: ^,
- * meaning that we should get very few collisions in the end. */
- csc->relocs_hashlist[hash] = reloc;
- csc->reloc_indices_hashlist[hash] = i;
- /*printf("write_reloc collision, hash: %i, handle: %i\n", hash, bo->handle);*/
- return i;
- }
+ unsigned hash = bo->handle & (Elements(csc->reloc_indices_hashlist)-1);
+ int i = csc->reloc_indices_hashlist[hash];
+
+ /* not found or found */
+ if (i == -1 || csc->relocs_bo[i] == bo)
+ return i;
+
+ /* Hash collision, look for the BO in the list of relocs linearly. */
+ for (i = csc->crelocs - 1; i >= 0; i--) {
+ if (csc->relocs_bo[i] == bo) {
+ /* Put this reloc in the hash list.
+ * This will prevent additional hash collisions if there are
+ * several consecutive get_reloc calls for the same buffer.
+ *
+ * Example: Assuming buffers A,B,C collide in the hash list,
+ * the following sequence of relocs:
+ * AAAAAAAAAAABBBBBBBBBBBBBBCCCCCCCC
+ * will collide here: ^ and here: ^,
+ * meaning that we should get very few collisions in the end. */
+ csc->reloc_indices_hashlist[hash] = i;
+ return i;