mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-03 17:38:25 +02:00
poly: Refactor poly_unroll_restart for general purpose unrolling
Defines a more general purpose version of `poly_unroll_restart` named `poly_unroll_geometry`, which allows unrolling without an input index buffer by separating the input and output index sizes. This allows it to be used for additional use cases, such as unrolling triangle fans or changing index types, where the draw may not necessarily be indexed or the input and output index types are not the same. `poly_unroll_restart` remains as an alias with the same declaration as before. Reviewed-by: Aitor Camacho <aitor@lunarg.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41568>
This commit is contained in:
parent
72f02d6e89
commit
69a5105aad
2 changed files with 47 additions and 21 deletions
|
|
@ -134,7 +134,8 @@ poly_work_group_first_true(bool cond, local void *scratch)
|
|||
static inline global void *
|
||||
poly_setup_unroll_for_draw(global struct poly_heap *heap,
|
||||
constant uint *in_draw, global uint *out_draw,
|
||||
enum mesa_prim mode, uint index_size_B)
|
||||
enum mesa_prim mode, uint in_index_size_B,
|
||||
uint out_index_size_B)
|
||||
{
|
||||
/* Determine an upper bound on the memory required for the index buffer.
|
||||
* Restarts only decrease the unrolled index buffer size, so the maximum size
|
||||
|
|
@ -142,7 +143,7 @@ poly_setup_unroll_for_draw(global struct poly_heap *heap,
|
|||
*/
|
||||
uint max_prims = u_decomposed_prims_for_vertices(mode, in_draw[0]);
|
||||
uint max_verts = max_prims * mesa_vertices_per_prim(mode);
|
||||
uint alloc_size = max_verts * index_size_B;
|
||||
uint alloc_size = max_verts * out_index_size_B;
|
||||
|
||||
/* Allocate unrolled index buffer.
|
||||
*
|
||||
|
|
@ -152,26 +153,28 @@ poly_setup_unroll_for_draw(global struct poly_heap *heap,
|
|||
uint old_heap_bottom_B = poly_heap_alloc_offs(heap, alloc_size);
|
||||
|
||||
/* Setup most of the descriptor. Count will be determined after unroll. */
|
||||
out_draw[1] = in_draw[1]; /* instance count */
|
||||
out_draw[2] = old_heap_bottom_B / index_size_B; /* index offset */
|
||||
out_draw[3] = in_draw[3]; /* index bias */
|
||||
out_draw[4] = in_draw[4]; /* base instance */
|
||||
uint vertex_offset_idx = in_index_size_B > 0 ? 3 : 2;
|
||||
out_draw[1] = in_draw[1]; /* instance count */
|
||||
out_draw[2] = old_heap_bottom_B / out_index_size_B; /* index offset */
|
||||
out_draw[3] = in_draw[vertex_offset_idx]; /* index bias */
|
||||
out_draw[4] = in_draw[vertex_offset_idx + 1]; /* base instance */
|
||||
|
||||
/* Return the index buffer we allocated */
|
||||
return (global uchar *)heap->base + old_heap_bottom_B;
|
||||
}
|
||||
|
||||
static inline void
|
||||
poly_unroll_restart(global uint32_t *out_draw,
|
||||
global struct poly_heap *heap,
|
||||
constant uint *in_draw,
|
||||
uint64_t index_buffer,
|
||||
uint32_t index_buffer_range_el,
|
||||
uint32_t index_size_B,
|
||||
uint32_t restart_index,
|
||||
uint32_t flatshade_first,
|
||||
enum mesa_prim mode,
|
||||
local void *scratch)
|
||||
poly_unroll_geometry(global uint32_t *out_draw,
|
||||
global struct poly_heap *heap,
|
||||
constant uint *in_draw,
|
||||
uint64_t index_buffer,
|
||||
uint32_t index_buffer_range_el,
|
||||
uint32_t in_index_size_B,
|
||||
uint32_t out_index_size_B,
|
||||
uint32_t restart_index,
|
||||
uint32_t flatshade_first,
|
||||
enum mesa_prim mode,
|
||||
local void *scratch)
|
||||
{
|
||||
uint tid = cl_local_id.x;
|
||||
uint count = in_draw[0];
|
||||
|
|
@ -179,7 +182,8 @@ poly_unroll_restart(global uint32_t *out_draw,
|
|||
uintptr_t out_ptr;
|
||||
if (tid == 0) {
|
||||
out_ptr = (uintptr_t)poly_setup_unroll_for_draw(heap, in_draw, out_draw,
|
||||
mode, index_size_B);
|
||||
mode, in_index_size_B,
|
||||
out_index_size_B);
|
||||
if (get_num_sub_groups() > 1)
|
||||
*(uintptr_t *)scratch = out_ptr;
|
||||
}
|
||||
|
|
@ -192,7 +196,7 @@ poly_unroll_restart(global uint32_t *out_draw,
|
|||
}
|
||||
|
||||
uintptr_t in_ptr = (uintptr_t)(poly_index_buffer(
|
||||
index_buffer, index_buffer_range_el, in_draw[2], index_size_B));
|
||||
index_buffer, index_buffer_range_el, in_draw[2], in_index_size_B));
|
||||
|
||||
uint out_prims = 0;
|
||||
uint needle = 0;
|
||||
|
|
@ -204,7 +208,7 @@ poly_unroll_restart(global uint32_t *out_draw,
|
|||
uint idx = next_restart + tid;
|
||||
bool restart =
|
||||
idx >= count || poly_load_index(in_ptr, index_buffer_range_el, idx,
|
||||
index_size_B) == restart_index;
|
||||
in_index_size_B) == restart_index;
|
||||
|
||||
uint next_offs = poly_work_group_first_true(restart, scratch);
|
||||
|
||||
|
|
@ -225,9 +229,9 @@ poly_unroll_restart(global uint32_t *out_draw,
|
|||
|
||||
uint x = ((out_prims_base + i) * per_prim) + vtx;
|
||||
uint y = poly_load_index(in_ptr, index_buffer_range_el, offset,
|
||||
index_size_B);
|
||||
in_index_size_B);
|
||||
|
||||
poly_store_index(out_ptr, index_size_B, x, y);
|
||||
poly_store_index(out_ptr, out_index_size_B, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -239,6 +243,23 @@ poly_unroll_restart(global uint32_t *out_draw,
|
|||
out_draw[0] = out_prims * per_prim;
|
||||
}
|
||||
|
||||
static inline void
|
||||
poly_unroll_restart(global uint32_t *out_draw,
|
||||
global struct poly_heap *heap,
|
||||
constant uint *in_draw,
|
||||
uint64_t index_buffer,
|
||||
uint32_t index_buffer_range_el,
|
||||
uint32_t index_size_B,
|
||||
uint32_t restart_index,
|
||||
uint32_t flatshade_first,
|
||||
enum mesa_prim mode,
|
||||
local void *scratch)
|
||||
{
|
||||
poly_unroll_geometry(out_draw, heap, in_draw, index_buffer,
|
||||
index_buffer_range_el, index_size_B, index_size_B,
|
||||
restart_index, flatshade_first, mode, scratch);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
poly_count_restart_prims(constant uint *in_draw,
|
||||
uint64_t index_buffer,
|
||||
|
|
|
|||
|
|
@ -657,6 +657,11 @@ static uint
|
|||
poly_load_index(uintptr_t index_buffer, uint32_t index_buffer_range_el, uint id,
|
||||
uint index_size)
|
||||
{
|
||||
if (index_size == 0) {
|
||||
/* No index buffer, return vertex ID */
|
||||
return id;
|
||||
}
|
||||
|
||||
bool oob = id >= index_buffer_range_el;
|
||||
|
||||
/* If the load would be out-of-bounds, load the first element which is
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue