replace one-off mergesort with the one in core

This commit is contained in:
Anthony Pesch 2017-05-25 20:33:41 -04:00
parent c699ef62aa
commit 00534496b4
4 changed files with 25 additions and 55 deletions

View File

@ -21,26 +21,25 @@ static void merge(void *in, void *out, size_t size, int l, int m, int r,
}
}
static void mergesort_r(void *in, void *out, size_t size, int l, int r,
sort_cmp cmp) {
static void msort_r(void *in, void *out, size_t size, int l, int r,
sort_cmp cmp) {
if ((r - l) < 2) {
return;
}
int m = (l + r) / 2;
mergesort_r(out, in, size, l, m, cmp);
mergesort_r(out, in, size, m, r, cmp);
msort_r(out, in, size, l, m, cmp);
msort_r(out, in, size, m, r, cmp);
merge(in, out, size, l, m, r, cmp);
}
void mergesort_fixed(void *data, void *tmp, int num, size_t size,
sort_cmp cmp) {
void msort_noalloc(void *data, void *tmp, int num, size_t size, sort_cmp cmp) {
memcpy(tmp, data, num * size);
mergesort_r(tmp, data, size, 0, num, cmp);
msort_r(tmp, data, size, 0, num, cmp);
}
void mergesort(void *data, int num, size_t size, sort_cmp cmp) {
void msort(void *data, int num, size_t size, sort_cmp cmp) {
void *tmp = malloc(num * size);
mergesort_fixed(data, tmp, num, size, cmp);
msort_noalloc(data, tmp, num, size, cmp);
free(tmp);
}

View File

@ -6,7 +6,8 @@
/* returns if a is <= b */
typedef int (*sort_cmp)(const void *, const void *);
void mergesort_fixed(void *data, void *tmp, int num, size_t size, sort_cmp cmp);
void mergesort(void *data, int num, size_t size, sort_cmp cmp);
/* mergesort implementation, FreeBSD took the mergesort symbol */
void msort_noalloc(void *data, void *tmp, int num, size_t size, sort_cmp cmp);
void msort(void *data, int num, size_t size, sort_cmp cmp);
#endif

View File

@ -4,6 +4,7 @@
#include "core/assert.h"
#include "core/core.h"
#include "core/profiler.h"
#include "core/sort.h"
#include "hw/pvr/pixel_convert.h"
#include "hw/pvr/ta.h"
@ -791,50 +792,17 @@ static void tr_parse_vert_param(struct tr *tr, const struct tile_context *ctx,
static int sort_tmp[TA_MAX_SURFS];
static float sort_minz[TA_MAX_SURFS];
static void tr_merge_surfs(struct tr *tr, int *low, int *mid, int *high) {
int *i = low;
int *j = mid + 1;
int *k = sort_tmp;
int *end = sort_tmp + array_size(sort_tmp);
while (i <= mid && j <= high) {
DCHECK_LT(k, end);
if (sort_minz[*i] <= sort_minz[*j]) {
*(k++) = *(i++);
} else {
*(k++) = *(j++);
}
}
while (i <= mid) {
DCHECK_LT(k, end);
*(k++) = *(i++);
}
while (j <= high) {
DCHECK_LT(k, end);
*(k++) = *(j++);
}
memcpy(low, sort_tmp, (k - sort_tmp) * sizeof(sort_tmp[0]));
}
static void tr_sort_surfs(struct tr *tr, struct tr_list *list, int low,
int high) {
if (low >= high) {
return;
}
int mid = (low + high) / 2;
tr_sort_surfs(tr, list, low, mid);
tr_sort_surfs(tr, list, mid + 1, high);
tr_merge_surfs(tr, &list->surfs[low], &list->surfs[mid], &list->surfs[high]);
static int tr_compare_surf(const void *a, const void *b) {
int i = *(const int *)a;
int j = *(const int *)b;
return sort_minz[i] <= sort_minz[j];
}
static void tr_sort_render_list(struct tr *tr, struct tr_context *rc,
int list_type) {
PROF_ENTER("gpu", "tr_sort_render_list");
/* sort each surface from back to front based on its minz */
struct tr_list *list = &rc->lists[list_type];
for (int i = 0; i < list->num_surfs; i++) {
@ -852,8 +820,8 @@ static void tr_sort_render_list(struct tr *tr, struct tr_context *rc,
}
}
/* sort each surface from back to front based on its minz */
tr_sort_surfs(tr, list, 0, list->num_surfs - 1);
msort_noalloc(list->surfs, sort_tmp, list->num_surfs, sizeof(int),
&tr_compare_surf);
PROF_LEAVE();
}
@ -886,7 +854,8 @@ static void tr_reset(struct tr *tr, struct tr_context *rc) {
}
static void tr_render_list(struct render_backend *r,
const struct tr_context *rc, int list_type, int end_surf, int *stopped) {
const struct tr_context *rc, int list_type,
int end_surf, int *stopped) {
if (*stopped) {
return;
}
@ -907,7 +876,8 @@ static void tr_render_list(struct render_backend *r,
}
}
void tr_render_context_until(struct render_backend *r, const struct tr_context *rc, int end_surf) {
void tr_render_context_until(struct render_backend *r,
const struct tr_context *rc, int end_surf) {
PROF_ENTER("gpu", "tr_render_context_until");
int stopped = 0;

View File

@ -74,7 +74,7 @@ static void test_context(struct trace_cmd *cmd, struct test *tests,
maxw = MAX(maxw, entry->d.f);
}
mergesort(original, rc->num_verts, sizeof(struct depth_entry), &depth_cmpf);
msort(original, rc->num_verts, sizeof(struct depth_entry), &depth_cmpf);
for (int i = 0; i < num_tests; i++) {
struct test *test = &tests[i];
@ -90,7 +90,7 @@ static void test_context(struct trace_cmd *cmd, struct test *tests,
}
/* sort the vertices based on the depth value */
mergesort(tmp, rc->num_verts, sizeof(struct depth_entry), test->cmp);
msort(tmp, rc->num_verts, sizeof(struct depth_entry), test->cmp);
/* compare sorted results with original results */
for (int j = 0; j < rc->num_verts; j++) {