diff options
Diffstat (limited to 'src/gallium/include')
-rw-r--r-- | src/gallium/include/pipe/p_context.h | 42 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_defines.h | 1 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_screen.h | 21 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_state.h | 52 |
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 |