177 lines
4.6 KiB
C
177 lines
4.6 KiB
C
/*
|
|
* Copyright © 2022 Imagination Technologies Ltd.
|
|
*
|
|
* based in part on anv driver which is:
|
|
* Copyright © 2016 Intel Corporation
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef PVR_PACKET_HELPERS_H
|
|
#define PVR_PACKET_HELPERS_H
|
|
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#ifndef __pvr_validate_value
|
|
# define __pvr_validate_value(x)
|
|
#endif
|
|
|
|
#ifdef NDEBUG
|
|
# define NDEBUG_UNUSED __attribute__((unused))
|
|
#else
|
|
# define NDEBUG_UNUSED
|
|
#endif
|
|
|
|
#ifndef __pvr_address_type
|
|
# error #define __pvr_address_type before including this file
|
|
#endif
|
|
|
|
#ifndef __pvr_get_address
|
|
# error #define __pvr_get_address before including this file
|
|
#endif
|
|
|
|
union __pvr_value {
|
|
float f;
|
|
uint32_t dw;
|
|
};
|
|
|
|
static inline __attribute__((always_inline)) uint64_t __pvr_mbo(uint32_t start,
|
|
uint32_t end)
|
|
{
|
|
return (~0ull >> (64 - (end - start + 1))) << start;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint64_t
|
|
__pvr_uint(uint64_t v, uint32_t start, NDEBUG_UNUSED uint32_t end)
|
|
{
|
|
__pvr_validate_value(v);
|
|
|
|
#ifndef NDEBUG
|
|
const int width = end - start + 1;
|
|
if (width < 64) {
|
|
const uint64_t max = (1ull << width) - 1;
|
|
assert(v <= max);
|
|
}
|
|
#endif
|
|
|
|
return v << start;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint64_t
|
|
__pvr_sint(int64_t v, uint32_t start, uint32_t end)
|
|
{
|
|
const int width = end - start + 1;
|
|
|
|
__pvr_validate_value(v);
|
|
|
|
#ifndef NDEBUG
|
|
if (width < 64) {
|
|
const int64_t max = (1ll << (width - 1)) - 1;
|
|
const int64_t min = -(1ll << (width - 1));
|
|
assert(min <= v && v <= max);
|
|
}
|
|
#endif
|
|
|
|
const uint64_t mask = ~0ull >> (64 - width);
|
|
|
|
return (v & mask) << start;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint64_t
|
|
__pvr_offset(uint64_t v,
|
|
NDEBUG_UNUSED uint32_t start,
|
|
NDEBUG_UNUSED uint32_t end)
|
|
{
|
|
__pvr_validate_value(v);
|
|
#ifndef NDEBUG
|
|
uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start;
|
|
|
|
assert((v & ~mask) == 0);
|
|
#endif
|
|
|
|
return v;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint64_t
|
|
__pvr_address(__pvr_address_type address,
|
|
uint32_t shift,
|
|
uint32_t start,
|
|
uint32_t end)
|
|
{
|
|
uint64_t addr_u64 = __pvr_get_address(address);
|
|
uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start;
|
|
|
|
return ((addr_u64 >> shift) << start) & mask;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint32_t __pvr_float(float v)
|
|
{
|
|
__pvr_validate_value(v);
|
|
return ((union __pvr_value){ .f = (v) }).dw;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint64_t
|
|
__pvr_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
|
|
{
|
|
__pvr_validate_value(v);
|
|
|
|
const float factor = (1 << fract_bits);
|
|
|
|
#ifndef NDEBUG
|
|
const float max = ((1 << (end - start)) - 1) / factor;
|
|
const float min = -(1 << (end - start)) / factor;
|
|
assert(min <= v && v <= max);
|
|
#endif
|
|
|
|
const int64_t int_val = llroundf(v * factor);
|
|
const uint64_t mask = ~0ull >> (64 - (end - start + 1));
|
|
|
|
return (int_val & mask) << start;
|
|
}
|
|
|
|
static inline __attribute__((always_inline)) uint64_t
|
|
__pvr_ufixed(float v,
|
|
uint32_t start,
|
|
NDEBUG_UNUSED uint32_t end,
|
|
uint32_t fract_bits)
|
|
{
|
|
__pvr_validate_value(v);
|
|
|
|
const float factor = (1 << fract_bits);
|
|
|
|
#ifndef NDEBUG
|
|
const float max = ((1 << (end - start + 1)) - 1) / factor;
|
|
const float min = 0.0f;
|
|
assert(min <= v && v <= max);
|
|
#endif
|
|
|
|
const uint64_t uint_val = llroundf(v * factor);
|
|
|
|
return uint_val << start;
|
|
}
|
|
|
|
#undef NDEBUG_UNUSED
|
|
|
|
#endif /* PVR_PACKET_HELPERS_H */
|