summaryrefslogtreecommitdiff
path: root/src/gallium/include
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2021-09-15 22:46:39 -0400
committerMarge Bot <eric+marge@anholt.net>2021-10-01 14:51:23 +0000
commit1c66de323904a529bc03ca0be79feffd963e6d60 (patch)
treeb6356bc7d6ce2e2051eb1e824bc4ce7fa424cbb7 /src/gallium/include
parentd5218f08891650dd638c0484d237dfa4675f8d74 (diff)
gallium: add pipe_vertex_state and draw_vertex_state for display lists
The main motivation is to improve the score of viewperf13/snx. This new interface is designed to be optimal for display lists as implemented by the vbo module. It has much lower CPU overhead in the frontend, threaded context, and the driver. Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13050>
Diffstat (limited to 'src/gallium/include')
-rw-r--r--src/gallium/include/pipe/p_context.h42
-rw-r--r--src/gallium/include/pipe/p_defines.h1
-rw-r--r--src/gallium/include/pipe/p_screen.h21
-rw-r--r--src/gallium/include/pipe/p_state.h52
4 files changed, 116 insertions, 0 deletions
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index f5775e7470e..bedc9261bc7 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -51,6 +51,7 @@ struct pipe_device_reset_callback;
struct pipe_draw_info;
struct pipe_draw_indirect_info;
struct pipe_draw_start_count_bias;
+struct pipe_draw_vertex_state_info;
struct pipe_grid_info;
struct pipe_fence_handle;
struct pipe_framebuffer_state;
@@ -71,6 +72,7 @@ struct pipe_surface;
struct pipe_transfer;
struct pipe_vertex_buffer;
struct pipe_vertex_element;
+struct pipe_vertex_state;
struct pipe_video_buffer;
struct pipe_video_codec;
struct pipe_viewport_state;
@@ -142,6 +144,46 @@ struct pipe_context {
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count_bias *draws,
unsigned num_draws);
+
+ /**
+ * Multi draw for display lists.
+ *
+ * For more information, see pipe_vertex_state and
+ * pipe_draw_vertex_state_info.
+ *
+ * Explanation of partial_vertex_mask:
+ *
+ * 1. pipe_vertex_state::input::elements have a monotonic logical index
+ * determined by pipe_vertex_state::input::full_velem_mask, specifically,
+ * the position of the i-th bit set is the logical index of the i-th
+ * vertex element, up to 31.
+ *
+ * 2. pipe_vertex_state::input::partial_velem_mask is a subset of
+ * full_velem_mask where the bits set determine which vertex elements
+ * should be bound contiguously. The vertex elements corresponding to
+ * the bits not set in partial_velem_mask should be ignored.
+ *
+ * Those two allow creating pipe_vertex_state that has more vertex
+ * attributes than the vertex shader has inputs. The idea is that
+ * pipe_vertex_state can be used with any vertex shader that has the same
+ * number of inputs and same logical indices or less. This may sound like
+ * an overly complicated way to bind a subset of vertex elements, but it
+ * actually simplifies everything else:
+ *
+ * - In st/mesa, full_velem_mask is exactly the mask of enabled vertex
+ * attributes (VERT_ATTRIB_x) in the display list VAO, while
+ * partial_velem_mask is exactly the inputs_read mask of the vertex
+ * shader (also VERT_ATTRIB_x).
+ *
+ * - In the driver, some bit ops and popcnt is needed to assemble vertex
+ * elements very quickly.
+ */
+ void (*draw_vertex_state)(struct pipe_context *ctx,
+ struct pipe_vertex_state *state,
+ uint32_t partial_velem_mask,
+ struct pipe_draw_vertex_state_info info,
+ const struct pipe_draw_start_count_bias *draws,
+ unsigned num_draws);
/*@}*/
/**
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 0bc713db69b..123c2b4d0f6 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -994,6 +994,7 @@ enum pipe_cap
PIPE_CAP_SUPPORTED_PRIM_MODES,
PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART,
PIPE_CAP_PREFER_BACK_BUFFER_REUSE,
+ PIPE_CAP_DRAW_VERTEX_STATE,
PIPE_CAP_LAST,
/* XXX do not add caps after PIPE_CAP_LAST! */
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 4421bee5b0f..9176bf2b586 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -58,9 +58,23 @@ struct pipe_surface;
struct pipe_transfer;
struct pipe_box;
struct pipe_memory_info;
+struct pipe_vertex_buffer;
+struct pipe_vertex_element;
+struct pipe_vertex_state;
struct disk_cache;
struct driOptionCache;
struct u_transfer_helper;
+struct pipe_screen;
+
+typedef struct pipe_vertex_state *
+ (*pipe_create_vertex_state_func)(struct pipe_screen *screen,
+ struct pipe_vertex_buffer *buffer,
+ const struct pipe_vertex_element *elements,
+ unsigned num_elements,
+ struct pipe_resource *indexbuf,
+ uint32_t full_velem_mask);
+typedef void (*pipe_vertex_state_destroy_func)(struct pipe_screen *screen,
+ struct pipe_vertex_state *);
/**
* Gallium screen/adapter context. Basically everything
@@ -604,6 +618,13 @@ struct pipe_screen {
unsigned int (*get_dmabuf_modifier_planes)(struct pipe_screen *screen,
uint64_t modifier,
enum pipe_format format);
+
+ /**
+ * Vertex state CSO functions for precomputing vertex and index buffer
+ * states for display lists.
+ */
+ pipe_create_vertex_state_func create_vertex_state;
+ pipe_vertex_state_destroy_func vertex_state_destroy;
};
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 63833a8b19f..cc600e0c762 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -708,6 +708,39 @@ struct pipe_vertex_element
unsigned instance_divisor;
};
+/**
+ * Opaque refcounted constant state object encapsulating a vertex buffer,
+ * index buffer, and vertex elements. Used by display lists to bind those
+ * states and pass buffer references quickly.
+ *
+ * The state contains 1 index buffer, 0 or 1 vertex buffer, and 0 or more
+ * vertex elements.
+ *
+ * Constraints on the buffers to get the fastest codepath:
+ * - All buffer contents are considered immutable and read-only after
+ * initialization. This implies the following things.
+ * - No place is required to track whether these buffers are busy.
+ * - All CPU mappings of these buffers can be forced to UNSYNCHRONIZED by
+ * both drivers and common code unconditionally.
+ * - Buffer invalidation can be skipped by both drivers and common code
+ * unconditionally.
+ */
+struct pipe_vertex_state {
+ struct pipe_reference reference;
+ struct pipe_screen *screen;
+
+ /* The following structure is used as a key for util_vertex_state_cache
+ * to deduplicate identical state objects and thus enable more
+ * opportunities for draw merging.
+ */
+ struct {
+ struct pipe_resource *indexbuf;
+ struct pipe_vertex_buffer vbuffer;
+ unsigned num_elements;
+ struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS];
+ uint32_t full_velem_mask;
+ } input;
+};
struct pipe_draw_indirect_info
{
@@ -767,6 +800,25 @@ struct pipe_draw_start_count_bias {
};
/**
+ * Draw vertex state description. It's translated to pipe_draw_info as follows:
+ * - mode comes from this structure
+ * - index_size is 4
+ * - instance_count is 1
+ * - index.resource comes from pipe_vertex_state
+ * - everything else is 0
+ */
+struct pipe_draw_vertex_state_info {
+#if defined(__GNUC__)
+ /* sizeof(mode) == 1 because it's a packed enum. */
+ enum pipe_prim_type mode; /**< the mode of the primitive */
+#else
+ /* sizeof(mode) == 1 is required by draw merging in u_threaded_context. */
+ uint8_t mode; /**< the mode of the primitive */
+#endif
+ bool take_vertex_state_ownership; /**< for skipping reference counting */
+};
+
+/**
* Information to describe a draw_vbo call.
*/
struct pipe_draw_info