mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
poly/asahi: Pull a bunch of vertex_id_for helpers into poly/prim.h
There's nothing really CL-specific about any of these. Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com> Reviewed-by: Mary Guillemard <mary@mary.zone> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38404>
This commit is contained in:
parent
27b2290abe
commit
ddff3700a4
3 changed files with 152 additions and 275 deletions
|
|
@ -6,146 +6,11 @@
|
||||||
|
|
||||||
#include "compiler/libcl/libcl_vk.h"
|
#include "compiler/libcl/libcl_vk.h"
|
||||||
#include "poly/geometry.h"
|
#include "poly/geometry.h"
|
||||||
|
#include "poly/prim.h"
|
||||||
#include "poly/tessellator.h"
|
#include "poly/tessellator.h"
|
||||||
#include "util/macros.h"
|
#include "util/macros.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
|
||||||
/* Swap the two non-provoking vertices in odd triangles. This generates a vertex
|
|
||||||
* ID list with a consistent winding order.
|
|
||||||
*
|
|
||||||
* Holding prim and flatshade_first constant, the map : [0, 1, 2] -> [0, 1, 2]
|
|
||||||
* is its own inverse. It is hence used both vertex fetch and transform
|
|
||||||
* feedback.
|
|
||||||
*/
|
|
||||||
static uint
|
|
||||||
map_vertex_in_tri_strip(uint prim, uint vert, bool flatshade_first)
|
|
||||||
{
|
|
||||||
unsigned pv = flatshade_first ? 0 : 2;
|
|
||||||
|
|
||||||
bool even = (prim & 1) == 0;
|
|
||||||
bool provoking = vert == pv;
|
|
||||||
|
|
||||||
return (provoking || even) ? vert : ((3 - pv) - vert);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_line_loop(uint prim, uint vert, uint num_prims)
|
|
||||||
{
|
|
||||||
/* (0, 1), (1, 2), (2, 0) */
|
|
||||||
if (prim == (num_prims - 1) && vert == 1)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return prim + vert;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_tri_fan(uint prim, uint vert, bool flatshade_first)
|
|
||||||
{
|
|
||||||
/* Vulkan spec section 20.1.7 gives (i + 1, i + 2, 0) for a provoking
|
|
||||||
* first. OpenGL instead wants (0, i + 1, i + 2) with a provoking last.
|
|
||||||
* Piglit clipflat expects us to switch between these orders depending on
|
|
||||||
* provoking vertex, to avoid trivializing the fan.
|
|
||||||
*
|
|
||||||
* Rotate accordingly.
|
|
||||||
*/
|
|
||||||
if (flatshade_first) {
|
|
||||||
vert = (vert == 2) ? 0 : (vert + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The simpler form assuming last is provoking. */
|
|
||||||
return (vert == 0) ? 0 : prim + vert;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_tri_strip_adj(uint prim, uint vert, uint num_prims,
|
|
||||||
bool flatshade_first)
|
|
||||||
{
|
|
||||||
/* See Vulkan spec section 20.1.11 "Triangle Strips With Adjancency".
|
|
||||||
*
|
|
||||||
* There are different cases for first/middle/last/only primitives and for
|
|
||||||
* odd/even primitives. Determine which case we're in.
|
|
||||||
*/
|
|
||||||
bool last = prim == (num_prims - 1);
|
|
||||||
bool first = prim == 0;
|
|
||||||
bool even = (prim & 1) == 0;
|
|
||||||
bool even_or_first = even || first;
|
|
||||||
|
|
||||||
/* When the last vertex is provoking, we rotate the primitives
|
|
||||||
* accordingly. This seems required for OpenGL.
|
|
||||||
*/
|
|
||||||
if (!flatshade_first && !even_or_first) {
|
|
||||||
vert = (vert + 4u) % 6u;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Offsets per the spec. The spec lists 6 cases with 6 offsets. Luckily,
|
|
||||||
* there are lots of patterns we can exploit, avoiding a full 6x6 LUT.
|
|
||||||
*
|
|
||||||
* Here we assume the first vertex is provoking, the Vulkan default.
|
|
||||||
*/
|
|
||||||
uint offsets[6] = {
|
|
||||||
0,
|
|
||||||
first ? 1 : (even ? -2 : 3),
|
|
||||||
even_or_first ? 2 : 4,
|
|
||||||
last ? 5 : 6,
|
|
||||||
even_or_first ? 4 : 2,
|
|
||||||
even_or_first ? 3 : -2,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Ensure NIR can see thru the local array */
|
|
||||||
uint offset = 0;
|
|
||||||
for (uint i = 1; i < 6; ++i) {
|
|
||||||
if (i == vert)
|
|
||||||
offset = offsets[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally add to the base of the primitive */
|
|
||||||
return (prim * 2) + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_topology(enum mesa_prim mode, bool flatshade_first, uint prim,
|
|
||||||
uint vert, uint num_prims)
|
|
||||||
{
|
|
||||||
switch (mode) {
|
|
||||||
case MESA_PRIM_POINTS:
|
|
||||||
case MESA_PRIM_LINES:
|
|
||||||
case MESA_PRIM_TRIANGLES:
|
|
||||||
case MESA_PRIM_LINES_ADJACENCY:
|
|
||||||
case MESA_PRIM_TRIANGLES_ADJACENCY:
|
|
||||||
/* Regular primitive: every N vertices defines a primitive */
|
|
||||||
return (prim * mesa_vertices_per_prim(mode)) + vert;
|
|
||||||
|
|
||||||
case MESA_PRIM_LINE_LOOP:
|
|
||||||
return vertex_id_for_line_loop(prim, vert, num_prims);
|
|
||||||
|
|
||||||
case MESA_PRIM_LINE_STRIP:
|
|
||||||
case MESA_PRIM_LINE_STRIP_ADJACENCY:
|
|
||||||
/* (i, i + 1) or (i, ..., i + 3) */
|
|
||||||
return prim + vert;
|
|
||||||
|
|
||||||
case MESA_PRIM_TRIANGLE_STRIP: {
|
|
||||||
/* Order depends on the provoking vert.
|
|
||||||
*
|
|
||||||
* First: (0, 1, 2), (1, 3, 2), (2, 3, 4).
|
|
||||||
* Last: (0, 1, 2), (2, 1, 3), (2, 3, 4).
|
|
||||||
*
|
|
||||||
* Pull the (maybe swapped) vert from the corresponding primitive
|
|
||||||
*/
|
|
||||||
return prim + map_vertex_in_tri_strip(prim, vert, flatshade_first);
|
|
||||||
}
|
|
||||||
|
|
||||||
case MESA_PRIM_TRIANGLE_FAN:
|
|
||||||
return vertex_id_for_tri_fan(prim, vert, flatshade_first);
|
|
||||||
|
|
||||||
case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
|
|
||||||
return vertex_id_for_tri_strip_adj(prim, vert, num_prims,
|
|
||||||
flatshade_first);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KERNEL(1)
|
KERNEL(1)
|
||||||
libagx_increment_ia(global uint32_t *ia_vertices,
|
libagx_increment_ia(global uint32_t *ia_vertices,
|
||||||
global uint32_t *ia_primitives,
|
global uint32_t *ia_primitives,
|
||||||
|
|
@ -321,7 +186,7 @@ libagx_unroll_restart(global struct poly_heap *heap, uint64_t index_buffer,
|
||||||
for (uint i = tid; i < subprims; i += 1024) {
|
for (uint i = tid; i < subprims; i += 1024) {
|
||||||
for (uint vtx = 0; vtx < per_prim; ++vtx) {
|
for (uint vtx = 0; vtx < per_prim; ++vtx) {
|
||||||
uint id =
|
uint id =
|
||||||
vertex_id_for_topology(mode, flatshade_first, i, vtx, subprims);
|
poly_vertex_id_for_topology(mode, flatshade_first, i, vtx, subprims);
|
||||||
uint offset = needle + id;
|
uint offset = needle + id;
|
||||||
|
|
||||||
uint x = ((out_prims_base + i) * per_prim) + vtx;
|
uint x = ((out_prims_base + i) * per_prim) + vtx;
|
||||||
|
|
|
||||||
|
|
@ -7,30 +7,13 @@
|
||||||
|
|
||||||
#include "compiler/libcl/libcl_vk.h"
|
#include "compiler/libcl/libcl_vk.h"
|
||||||
#include "poly/geometry.h"
|
#include "poly/geometry.h"
|
||||||
|
#include "poly/prim.h"
|
||||||
#include "poly/tessellator.h"
|
#include "poly/tessellator.h"
|
||||||
#include "util/macros.h"
|
#include "util/macros.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
|
||||||
uint64_t nir_ro_to_rw_poly(uint64_t address);
|
uint64_t nir_ro_to_rw_poly(uint64_t address);
|
||||||
|
|
||||||
/* Swap the two non-provoking vertices in odd triangles. This generates a vertex
|
|
||||||
* ID list with a consistent winding order.
|
|
||||||
*
|
|
||||||
* Holding prim and flatshade_first constant, the map : [0, 1, 2] -> [0, 1, 2]
|
|
||||||
* is its own inverse. It is hence used both vertex fetch and transform
|
|
||||||
* feedback.
|
|
||||||
*/
|
|
||||||
static uint
|
|
||||||
map_vertex_in_tri_strip(uint prim, uint vert, bool flatshade_first)
|
|
||||||
{
|
|
||||||
unsigned pv = flatshade_first ? 0 : 2;
|
|
||||||
|
|
||||||
bool even = (prim & 1) == 0;
|
|
||||||
bool provoking = vert == pv;
|
|
||||||
|
|
||||||
return (provoking || even) ? vert : ((3 - pv) - vert);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint
|
static inline uint
|
||||||
xfb_prim(uint id, uint n, uint copy)
|
xfb_prim(uint id, uint n, uint copy)
|
||||||
{
|
{
|
||||||
|
|
@ -60,7 +43,7 @@ poly_xfb_vertex_offset(uint n, uint invocation_base_prim, uint strip_base_prim,
|
||||||
uint vert = vert_0 - copy;
|
uint vert = vert_0 - copy;
|
||||||
|
|
||||||
if (n == 3) {
|
if (n == 3) {
|
||||||
vert = map_vertex_in_tri_strip(prim, vert, flatshade_first);
|
vert = poly_map_vertex_in_tri_strip(prim, vert, flatshade_first);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tally up in the whole buffer */
|
/* Tally up in the whole buffer */
|
||||||
|
|
@ -78,16 +61,6 @@ poly_xfb_vertex_address(constant struct poly_geometry_params *p, uint index,
|
||||||
return (uintptr_t)(p->xfb_base[buffer]) + xfb_offset;
|
return (uintptr_t)(p->xfb_base[buffer]) + xfb_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_line_loop(uint prim, uint vert, uint num_prims)
|
|
||||||
{
|
|
||||||
/* (0, 1), (1, 2), (2, 0) */
|
|
||||||
if (prim == (num_prims - 1) && vert == 1)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return prim + vert;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint
|
uint
|
||||||
poly_vertex_id_for_line_class(enum mesa_prim mode, uint prim, uint vert,
|
poly_vertex_id_for_line_class(enum mesa_prim mode, uint prim, uint vert,
|
||||||
uint num_prims)
|
uint num_prims)
|
||||||
|
|
@ -102,24 +75,6 @@ poly_vertex_id_for_line_class(enum mesa_prim mode, uint prim, uint vert,
|
||||||
return prim + vert;
|
return prim + vert;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_tri_fan(uint prim, uint vert, bool flatshade_first)
|
|
||||||
{
|
|
||||||
/* Vulkan spec section 20.1.7 gives (i + 1, i + 2, 0) for a provoking
|
|
||||||
* first. OpenGL instead wants (0, i + 1, i + 2) with a provoking last.
|
|
||||||
* Piglit clipflat expects us to switch between these orders depending on
|
|
||||||
* provoking vertex, to avoid trivializing the fan.
|
|
||||||
*
|
|
||||||
* Rotate accordingly.
|
|
||||||
*/
|
|
||||||
if (flatshade_first) {
|
|
||||||
vert = (vert == 2) ? 0 : (vert + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The simpler form assuming last is provoking. */
|
|
||||||
return (vert == 0) ? 0 : prim + vert;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint
|
uint
|
||||||
poly_vertex_id_for_tri_class(enum mesa_prim mode, uint prim, uint vert,
|
poly_vertex_id_for_tri_class(enum mesa_prim mode, uint prim, uint vert,
|
||||||
bool flatshade_first)
|
bool flatshade_first)
|
||||||
|
|
@ -158,108 +113,18 @@ poly_vertex_id_for_line_adj_class(enum mesa_prim mode, uint prim, uint vert)
|
||||||
return prim + vert;
|
return prim + vert;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_tri_strip_adj(uint prim, uint vert, uint num_prims,
|
|
||||||
bool flatshade_first)
|
|
||||||
{
|
|
||||||
/* See Vulkan spec section 20.1.11 "Triangle Strips With Adjancency".
|
|
||||||
*
|
|
||||||
* There are different cases for first/middle/last/only primitives and for
|
|
||||||
* odd/even primitives. Determine which case we're in.
|
|
||||||
*/
|
|
||||||
bool last = prim == (num_prims - 1);
|
|
||||||
bool first = prim == 0;
|
|
||||||
bool even = (prim & 1) == 0;
|
|
||||||
bool even_or_first = even || first;
|
|
||||||
|
|
||||||
/* When the last vertex is provoking, we rotate the primitives
|
|
||||||
* accordingly. This seems required for OpenGL.
|
|
||||||
*/
|
|
||||||
if (!flatshade_first && !even_or_first) {
|
|
||||||
vert = (vert + 4u) % 6u;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Offsets per the spec. The spec lists 6 cases with 6 offsets. Luckily,
|
|
||||||
* there are lots of patterns we can exploit, avoiding a full 6x6 LUT.
|
|
||||||
*
|
|
||||||
* Here we assume the first vertex is provoking, the Vulkan default.
|
|
||||||
*/
|
|
||||||
uint offsets[6] = {
|
|
||||||
0,
|
|
||||||
first ? 1 : (even ? -2 : 3),
|
|
||||||
even_or_first ? 2 : 4,
|
|
||||||
last ? 5 : 6,
|
|
||||||
even_or_first ? 4 : 2,
|
|
||||||
even_or_first ? 3 : -2,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Ensure NIR can see thru the local array */
|
|
||||||
uint offset = 0;
|
|
||||||
for (uint i = 1; i < 6; ++i) {
|
|
||||||
if (i == vert)
|
|
||||||
offset = offsets[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally add to the base of the primitive */
|
|
||||||
return (prim * 2) + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint
|
uint
|
||||||
poly_vertex_id_for_tri_adj_class(enum mesa_prim mode, uint prim, uint vert,
|
poly_vertex_id_for_tri_adj_class(enum mesa_prim mode, uint prim, uint vert,
|
||||||
uint nr, bool flatshade_first)
|
uint nr, bool flatshade_first)
|
||||||
{
|
{
|
||||||
/* Tri adj list or tri adj strip */
|
/* Tri adj list or tri adj strip */
|
||||||
if (mode == MESA_PRIM_TRIANGLE_STRIP_ADJACENCY) {
|
if (mode == MESA_PRIM_TRIANGLE_STRIP_ADJACENCY) {
|
||||||
return vertex_id_for_tri_strip_adj(prim, vert, nr, flatshade_first);
|
return poly_vertex_id_for_tri_strip_adj(prim, vert, nr, flatshade_first);
|
||||||
} else {
|
} else {
|
||||||
return (6 * prim) + vert;
|
return (6 * prim) + vert;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint
|
|
||||||
vertex_id_for_topology(enum mesa_prim mode, bool flatshade_first, uint prim,
|
|
||||||
uint vert, uint num_prims)
|
|
||||||
{
|
|
||||||
switch (mode) {
|
|
||||||
case MESA_PRIM_POINTS:
|
|
||||||
case MESA_PRIM_LINES:
|
|
||||||
case MESA_PRIM_TRIANGLES:
|
|
||||||
case MESA_PRIM_LINES_ADJACENCY:
|
|
||||||
case MESA_PRIM_TRIANGLES_ADJACENCY:
|
|
||||||
/* Regular primitive: every N vertices defines a primitive */
|
|
||||||
return (prim * mesa_vertices_per_prim(mode)) + vert;
|
|
||||||
|
|
||||||
case MESA_PRIM_LINE_LOOP:
|
|
||||||
return vertex_id_for_line_loop(prim, vert, num_prims);
|
|
||||||
|
|
||||||
case MESA_PRIM_LINE_STRIP:
|
|
||||||
case MESA_PRIM_LINE_STRIP_ADJACENCY:
|
|
||||||
/* (i, i + 1) or (i, ..., i + 3) */
|
|
||||||
return prim + vert;
|
|
||||||
|
|
||||||
case MESA_PRIM_TRIANGLE_STRIP: {
|
|
||||||
/* Order depends on the provoking vert.
|
|
||||||
*
|
|
||||||
* First: (0, 1, 2), (1, 3, 2), (2, 3, 4).
|
|
||||||
* Last: (0, 1, 2), (2, 1, 3), (2, 3, 4).
|
|
||||||
*
|
|
||||||
* Pull the (maybe swapped) vert from the corresponding primitive
|
|
||||||
*/
|
|
||||||
return prim + map_vertex_in_tri_strip(prim, vert, flatshade_first);
|
|
||||||
}
|
|
||||||
|
|
||||||
case MESA_PRIM_TRIANGLE_FAN:
|
|
||||||
return vertex_id_for_tri_fan(prim, vert, flatshade_first);
|
|
||||||
|
|
||||||
case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
|
|
||||||
return vertex_id_for_tri_strip_adj(prim, vert, num_prims,
|
|
||||||
flatshade_first);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint
|
uint
|
||||||
poly_map_to_line_adj(uint id)
|
poly_map_to_line_adj(uint id)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
147
src/poly/prim.h
Normal file
147
src/poly/prim.h
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Alyssa Rosenzweig
|
||||||
|
* Copyright 2023 Valve Corporation
|
||||||
|
* Copyright 2025 Collabora Ltd.
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "compiler/libcl/libcl.h"
|
||||||
|
#include "compiler/shader_enums.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Swap the two non-provoking vertices in odd triangles. This generates a vertex
|
||||||
|
* ID list with a consistent winding order.
|
||||||
|
*
|
||||||
|
* Holding prim and flatshade_first constant, the map : [0, 1, 2] -> [0, 1, 2]
|
||||||
|
* is its own inverse. It is hence used both vertex fetch and transform
|
||||||
|
* feedback.
|
||||||
|
*/
|
||||||
|
static inline uint32_t
|
||||||
|
poly_map_vertex_in_tri_strip(uint32_t prim, uint32_t vert, bool flatshade_first)
|
||||||
|
{
|
||||||
|
unsigned pv = flatshade_first ? 0 : 2;
|
||||||
|
|
||||||
|
bool even = (prim & 1) == 0;
|
||||||
|
bool provoking = vert == pv;
|
||||||
|
|
||||||
|
return (provoking || even) ? vert : ((3 - pv) - vert);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
poly_vertex_id_for_line_loop(uint32_t prim, uint32_t vert, uint32_t num_prims)
|
||||||
|
{
|
||||||
|
/* (0, 1), (1, 2), (2, 0) */
|
||||||
|
if (prim == (num_prims - 1) && vert == 1)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return prim + vert;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
poly_vertex_id_for_tri_fan(uint32_t prim, uint32_t vert, bool flatshade_first)
|
||||||
|
{
|
||||||
|
/* Vulkan spec section 20.1.7 gives (i + 1, i + 2, 0) for a provoking
|
||||||
|
* first. OpenGL instead wants (0, i + 1, i + 2) with a provoking last.
|
||||||
|
* Piglit clipflat expects us to switch between these orders depending on
|
||||||
|
* provoking vertex, to avoid trivializing the fan.
|
||||||
|
*
|
||||||
|
* Rotate accordingly.
|
||||||
|
*/
|
||||||
|
if (flatshade_first) {
|
||||||
|
vert = (vert == 2) ? 0 : (vert + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The simpler form assuming last is provoking. */
|
||||||
|
return (vert == 0) ? 0 : prim + vert;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
poly_vertex_id_for_tri_strip_adj(uint32_t prim, uint32_t vert,
|
||||||
|
uint32_t num_prims, bool flatshade_first)
|
||||||
|
{
|
||||||
|
/* See Vulkan spec section 20.1.11 "Triangle Strips With Adjancency".
|
||||||
|
*
|
||||||
|
* There are different cases for first/middle/last/only primitives and for
|
||||||
|
* odd/even primitives. Determine which case we're in.
|
||||||
|
*/
|
||||||
|
bool last = prim == (num_prims - 1);
|
||||||
|
bool first = prim == 0;
|
||||||
|
bool even = (prim & 1) == 0;
|
||||||
|
bool even_or_first = even || first;
|
||||||
|
|
||||||
|
/* When the last vertex is provoking, we rotate the primitives
|
||||||
|
* accordingly. This seems required for OpenGL.
|
||||||
|
*/
|
||||||
|
if (!flatshade_first && !even_or_first) {
|
||||||
|
vert = (vert + 4u) % 6u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Offsets per the spec. The spec lists 6 cases with 6 offsets. Luckily,
|
||||||
|
* there are lots of patterns we can exploit, avoiding a full 6x6 LUT.
|
||||||
|
*
|
||||||
|
* Here we assume the first vertex is provoking, the Vulkan default.
|
||||||
|
*/
|
||||||
|
uint32_t offsets[6] = {
|
||||||
|
0,
|
||||||
|
first ? 1 : (even ? -2 : 3),
|
||||||
|
even_or_first ? 2 : 4,
|
||||||
|
last ? 5 : 6,
|
||||||
|
even_or_first ? 4 : 2,
|
||||||
|
even_or_first ? 3 : -2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Ensure NIR can see thru the local array */
|
||||||
|
uint32_t offset = 0;
|
||||||
|
for (uint32_t i = 1; i < 6; ++i) {
|
||||||
|
if (i == vert)
|
||||||
|
offset = offsets[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally add to the base of the primitive */
|
||||||
|
return (prim * 2) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
poly_vertex_id_for_topology(enum mesa_prim mode, bool flatshade_first,
|
||||||
|
uint32_t prim, uint32_t vert, uint32_t num_prims)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case MESA_PRIM_POINTS:
|
||||||
|
case MESA_PRIM_LINES:
|
||||||
|
case MESA_PRIM_TRIANGLES:
|
||||||
|
case MESA_PRIM_LINES_ADJACENCY:
|
||||||
|
case MESA_PRIM_TRIANGLES_ADJACENCY:
|
||||||
|
/* Regular primitive: every N vertices defines a primitive */
|
||||||
|
return (prim * mesa_vertices_per_prim(mode)) + vert;
|
||||||
|
|
||||||
|
case MESA_PRIM_LINE_LOOP:
|
||||||
|
return poly_vertex_id_for_line_loop(prim, vert, num_prims);
|
||||||
|
|
||||||
|
case MESA_PRIM_LINE_STRIP:
|
||||||
|
case MESA_PRIM_LINE_STRIP_ADJACENCY:
|
||||||
|
/* (i, i + 1) or (i, ..., i + 3) */
|
||||||
|
return prim + vert;
|
||||||
|
|
||||||
|
case MESA_PRIM_TRIANGLE_STRIP: {
|
||||||
|
/* Order depends on the provoking vert.
|
||||||
|
*
|
||||||
|
* First: (0, 1, 2), (1, 3, 2), (2, 3, 4).
|
||||||
|
* Last: (0, 1, 2), (2, 1, 3), (2, 3, 4).
|
||||||
|
*
|
||||||
|
* Pull the (maybe swapped) vert from the corresponding primitive
|
||||||
|
*/
|
||||||
|
return prim + poly_map_vertex_in_tri_strip(prim, vert, flatshade_first);
|
||||||
|
}
|
||||||
|
|
||||||
|
case MESA_PRIM_TRIANGLE_FAN:
|
||||||
|
return poly_vertex_id_for_tri_fan(prim, vert, flatshade_first);
|
||||||
|
|
||||||
|
case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
|
||||||
|
return poly_vertex_id_for_tri_strip_adj(prim, vert, num_prims,
|
||||||
|
flatshade_first);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue