summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_resource.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-10-18 12:50:05 +0100
committerEric Anholt <[email protected]>2014-10-19 08:44:56 +0100
commit6212d2402df4ad0658cbb98ce889e35ef5f32fa3 (patch)
tree23b3d5128082694cf8c62c2f62ff779475f0b776 /src/gallium/drivers/vc4/vc4_resource.c
parent572fba95e4cd85aebdde9bd757c17f719af2af04 (diff)
vc4: Translate 4-byte index buffers to 2 bytes.
Fixes assertion failures in 14 piglit tests (half of which now pass).
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_resource.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index 803d3575f09..c198ab94f43 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -512,6 +512,52 @@ vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
shadow->writes = orig->writes;
}
+/**
+ * Converts a 4-byte index buffer to 2 bytes.
+ *
+ * Since GLES2 only has support for 1 and 2-byte indices, the hardware doesn't
+ * include 4-byte index support, and we have to shrink it down.
+ *
+ * There's no fallback support for when indices end up being larger than 2^16,
+ * though it will at least assertion fail. Also, if the original index data
+ * 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 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 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;
+}
+
void
vc4_resource_screen_init(struct pipe_screen *pscreen)
{