summaryrefslogtreecommitdiff
path: root/src/gallium/include
diff options
context:
space:
mode:
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