pan/lib: Inline pan_atributes.c in pan_encoder.h

We are going to need those functions in indirect CL codepaths.

Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com>
Acked-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Olivia Lee <olivia.lee@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35490>
This commit is contained in:
Mary Guillemard
2025-06-11 10:57:17 +02:00
parent c1cd05771f
commit 5743bd703d
3 changed files with 56 additions and 96 deletions
-1
View File
@@ -40,7 +40,6 @@ endforeach
libpanfrost_lib_files = files(
'pan_encoder.h',
'pan_attributes.c',
'pan_blend.c',
'pan_clear.c',
'pan_earlyzs.c',
-92
View File
@@ -1,92 +0,0 @@
/*
* Copyright (C) 2019 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include "util/u_math.h"
#include "pan_encoder.h"
/* This file handles attribute descriptors. The
* bulk of the complexity is from instancing. See mali_job for
* notes on how this works. But basically, for small vertex
* counts, we have a lookup table, and for large vertex counts,
* we look at the high bits as a heuristic. This has to match
* exactly how the hardware calculates this (which is why the
* algorithm is so weird) or else instancing will break. */
unsigned
pan_padded_vertex_count(unsigned vertex_count)
{
if (vertex_count < 10)
return vertex_count;
if (vertex_count < 20)
return (vertex_count + 1) & ~1;
/* First, we have to find the highest set one */
unsigned highest = 32 - __builtin_clz(vertex_count);
/* Using that, we mask out the highest 4-bits */
unsigned n = highest - 4;
unsigned nibble = (vertex_count >> n) & 0xF;
/* Great, we have the nibble. Now we can just try possibilities. Note
* that we don't care about the bottom most bit in most cases, and we
* know the top bit must be 1 */
unsigned middle_two = (nibble >> 1) & 0x3;
switch (middle_two) {
case 0b00:
if (!(nibble & 1))
return (1 << n) * 9;
else
return (1 << (n + 1)) * 5;
case 0b01:
return (1 << (n + 2)) * 3;
case 0b10:
return (1 << (n + 1)) * 7;
case 0b11:
return (1 << (n + 4));
default:
return 0; /* unreachable */
}
}
unsigned
pan_compute_magic_divisor(unsigned hw_divisor, unsigned *divisor_r,
unsigned *divisor_e)
{
unsigned r = util_logbase2(hw_divisor);
uint64_t shift_hi = 32 + r;
uint64_t t = (uint64_t)1 << shift_hi;
uint64_t f0 = t + hw_divisor / 2;
uint64_t fi = f0 / hw_divisor;
uint64_t ff = f0 - fi * hw_divisor;
uint64_t d = fi - (1ul << 31);
*divisor_r = r;
*divisor_e = ff > hw_divisor / 2 ? 1 : 0;
return d;
}
+56 -3
View File
@@ -76,10 +76,63 @@ unsigned pan_get_total_stack_size(unsigned thread_size,
/* Attributes / instancing */
unsigned pan_padded_vertex_count(unsigned vertex_count);
static inline unsigned
pan_padded_vertex_count(unsigned vertex_count)
{
if (vertex_count < 10)
return vertex_count;
unsigned pan_compute_magic_divisor(unsigned hw_divisor, unsigned *divisor_r,
unsigned *divisor_e);
if (vertex_count < 20)
return (vertex_count + 1) & ~1;
/* First, we have to find the highest set one */
unsigned highest = 32 - __builtin_clz(vertex_count);
/* Using that, we mask out the highest 4-bits */
unsigned n = highest - 4;
unsigned nibble = (vertex_count >> n) & 0xF;
/* Great, we have the nibble. Now we can just try possibilities. Note
* that we don't care about the bottom most bit in most cases, and we
* know the top bit must be 1 */
unsigned middle_two = (nibble >> 1) & 0x3;
switch (middle_two) {
case 0b00:
if (!(nibble & 1))
return (1 << n) * 9;
else
return (1 << (n + 1)) * 5;
case 0b01:
return (1 << (n + 2)) * 3;
case 0b10:
return (1 << (n + 1)) * 7;
case 0b11:
return (1 << (n + 4));
default:
return 0; /* unreachable */
}
}
static inline unsigned
pan_compute_magic_divisor(unsigned hw_divisor, unsigned *divisor_r,
unsigned *divisor_e)
{
unsigned r = util_logbase2(hw_divisor);
uint64_t shift_hi = 32 + r;
uint64_t t = (uint64_t)1 << shift_hi;
uint64_t f0 = t + hw_divisor / 2;
uint64_t fi = f0 / hw_divisor;
uint64_t ff = f0 - fi * hw_divisor;
uint64_t d = fi - (1ul << 31);
*divisor_r = r;
*divisor_e = ff > hw_divisor / 2 ? 1 : 0;
return d;
}
#ifdef PAN_ARCH
/* Records for gl_VertexID and gl_InstanceID use special encodings on Midgard */