vc4: Just stream out fallback IB contents.
The idea I had when I wrote the original shadow code was that you'd see a set_index_buffer to the IB, then a bunch of draws out of it. What's actually happening in openarena is that set_index_buffer occurs at every draw, so we end up making a new shadow BO every time, and converting more of the BO than is actually used in the draw. While I could maybe come up with a better caching scheme, for now just do the simple thing that doesn't result in a new shadow IB allocation per draw. Improves performance of isosurf in drawelements mode by 58.7967% +/- 3.86152% (n=8).
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_surface.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "vc4_screen.h"
|
||||
#include "vc4_context.h"
|
||||
@@ -638,41 +639,37 @@ vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
|
||||
* was in user memory, it would be nice to not have uploaded it to a VBO
|
||||
* before translating.
|
||||
*/
|
||||
void
|
||||
vc4_update_shadow_index_buffer(struct pipe_context *pctx,
|
||||
const struct pipe_index_buffer *ib)
|
||||
struct pipe_resource *
|
||||
vc4_get_shadow_index_buffer(struct pipe_context *pctx,
|
||||
const struct pipe_index_buffer *ib,
|
||||
uint32_t count,
|
||||
uint32_t *shadow_offset)
|
||||
{
|
||||
struct vc4_resource *shadow = vc4_resource(ib->buffer);
|
||||
struct vc4_resource *orig = vc4_resource(shadow->shadow_parent);
|
||||
uint32_t count = shadow->base.b.width0 / 2;
|
||||
|
||||
if (shadow->writes == orig->writes)
|
||||
return;
|
||||
|
||||
struct vc4_context *vc4 = vc4_context(pctx);
|
||||
struct vc4_resource *orig = vc4_resource(ib->buffer);
|
||||
perf_debug("Fallback conversion for %d uint indices\n", count);
|
||||
|
||||
void *data;
|
||||
struct pipe_resource *shadow_rsc = NULL;
|
||||
u_upload_alloc(vc4->uploader, 0, count * 2,
|
||||
shadow_offset, &shadow_rsc, &data);
|
||||
uint16_t *dst = data;
|
||||
|
||||
struct pipe_transfer *src_transfer;
|
||||
uint32_t *src = pipe_buffer_map_range(pctx, &orig->base.b,
|
||||
ib->offset,
|
||||
count * 4,
|
||||
PIPE_TRANSFER_READ, &src_transfer);
|
||||
|
||||
struct pipe_transfer *dst_transfer;
|
||||
uint16_t *dst = pipe_buffer_map_range(pctx, &shadow->base.b,
|
||||
0,
|
||||
count * 2,
|
||||
PIPE_TRANSFER_WRITE, &dst_transfer);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t src_index = src[i];
|
||||
assert(src_index <= 0xffff);
|
||||
dst[i] = src_index;
|
||||
}
|
||||
|
||||
pctx->transfer_unmap(pctx, dst_transfer);
|
||||
pctx->transfer_unmap(pctx, src_transfer);
|
||||
|
||||
shadow->writes = orig->writes;
|
||||
return shadow_rsc;
|
||||
}
|
||||
|
||||
void
|
||||
|
Reference in New Issue
Block a user