[Mesa-dev] [RFC 2/3] u_vbuf: add logic to use a limited number of vbufs
Christian Gmeiner
christian.gmeiner at gmail.com
Sat Jun 11 19:21:52 UTC 2016
From: "Wladimir J. van der Laan" <laanwj at gmail.com>
Make it possible to limit the number of vertex buffers as there exist
GPUs with less then 32 supported vertex buffers.
Signed-off-by: Wladimir J. van der Laan <laanwj at gmail.com>
---
src/gallium/auxiliary/util/u_vbuf.c | 45 +++++++++++++++++++++++++++++++------
src/gallium/auxiliary/util/u_vbuf.h | 3 +++
2 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 5b4e527..464c279 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -184,6 +184,8 @@ struct u_vbuf {
uint32_t incompatible_vb_mask; /* each bit describes a corresp. buffer */
/* Which buffer has a non-zero stride. */
uint32_t nonzero_stride_vb_mask; /* each bit describes a corresp. buffer */
+ /* Which buffers are allowed (supported by hardware). */
+ uint32_t allowed_vb_mask;
};
static void *
@@ -291,10 +293,14 @@ boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
caps->user_vertex_buffers =
screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS);
+ caps->max_vertex_buffers =
+ screen->get_param(screen, PIPE_CAP_MAX_VERTEX_BUFFERS);
+
if (!caps->buffer_offset_unaligned ||
!caps->buffer_stride_unaligned ||
!caps->velem_src_offset_unaligned ||
- !caps->user_vertex_buffers) {
+ !caps->user_vertex_buffers ||
+ !caps->max_vertex_buffers) {
fallback = TRUE;
}
@@ -313,6 +319,7 @@ u_vbuf_create(struct pipe_context *pipe,
mgr->cso_cache = cso_cache_create();
mgr->translate_cache = translate_cache_create();
memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
+ mgr->allowed_vb_mask = (1 << mgr->caps.max_vertex_buffers) - 1;
mgr->uploader = u_upload_create(pipe, 1024 * 1024,
PIPE_BIND_VERTEX_BUFFER,
@@ -523,14 +530,15 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
static boolean
u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
- unsigned mask[VB_NUM])
+ unsigned mask[VB_NUM],
+ unsigned extra_free_vb_mask)
{
unsigned type;
unsigned fallback_vbs[VB_NUM];
/* Set the bit for each buffer which is incompatible, or isn't set. */
uint32_t unused_vb_mask =
- mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
- ~mgr->enabled_vb_mask;
+ (mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
+ ~mgr->enabled_vb_mask | extra_free_vb_mask) & mgr->allowed_vb_mask;
memset(fallback_vbs, ~0, sizeof(fallback_vbs));
@@ -573,6 +581,7 @@ u_vbuf_translate_begin(struct u_vbuf *mgr,
unsigned i, type;
unsigned incompatible_vb_mask = mgr->incompatible_vb_mask &
mgr->ve->used_vb_mask;
+ unsigned extra_free_vb_mask = 0;
int start[VB_NUM] = {
start_vertex, /* VERTEX */
@@ -618,8 +627,15 @@ u_vbuf_translate_begin(struct u_vbuf *mgr,
assert(mask[VB_VERTEX] || mask[VB_INSTANCE] || mask[VB_CONST]);
+ /* In the case of unroll_indices, we can regard all non-constant
+ * vertex buffers with only non-instance vertex elements as incompatible
+ * and thus free.
+ */
+ if (unroll_indices)
+ extra_free_vb_mask = mask[VB_VERTEX] & ~mask[VB_INSTANCE];
+
/* Find free vertex buffer slots. */
- if (!u_vbuf_translate_find_free_vb_slots(mgr, mask)) {
+ if (!u_vbuf_translate_find_free_vb_slots(mgr, mask, extra_free_vb_mask)) {
return FALSE;
}
@@ -778,6 +794,17 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
}
}
+ if (used_buffers & ~mgr->allowed_vb_mask) {
+ /* More vertex buffers are used than the hardware supports. In
+ * principle, we only need to make sure that less vertex buffers are
+ * used, and mark some of the latter vertex buffers as incompatible.
+ * For now, mark all vertex buffers as incompatible.
+ */
+ ve->incompatible_vb_mask_any = used_buffers;
+ ve->compatible_vb_mask_any = 0;
+ ve->incompatible_elem_mask = (1 << count) - 1;
+ }
+
ve->used_vb_mask = used_buffers;
ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers;
ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers;
@@ -790,8 +817,12 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
}
}
- ve->driver_cso =
- pipe->create_vertex_elements_state(pipe, count, driver_attribs);
+ /* Only create driver CSO if no incompatible elements */
+ if (!ve->incompatible_elem_mask) {
+ ve->driver_cso =
+ pipe->create_vertex_elements_state(pipe, count, driver_attribs);
+ }
+
return ve;
}
diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h
index 9e8b135..9ff9938 100644
--- a/src/gallium/auxiliary/util/u_vbuf.h
+++ b/src/gallium/auxiliary/util/u_vbuf.h
@@ -52,6 +52,9 @@ struct u_vbuf_caps {
/* Whether the driver supports user vertex buffers. */
unsigned user_vertex_buffers:1;
+
+ /* Maximum number of vertex buffers */
+ unsigned max_vertex_buffers:6;
};
--
2.5.5
More information about the mesa-dev
mailing list