1/* 2 * Copyright (C) 2016 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifndef MESA_V3D_PACKET_HELPERS_H 25#define MESA_V3D_PACKET_HELPERS_H 26 27#include <stdio.h> 28#include <stdint.h> 29#include <stdbool.h> 30#include <assert.h> 31#include <math.h> 32#include "util/u_math.h" 33 34#ifdef HAVE_VALGRIND 35#include <valgrind.h> 36#include <memcheck.h> 37#define VG(x) x 38#ifndef NDEBUG 39#define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x)) 40#endif 41#else 42#define VG(x) ((void)0) 43#endif 44 45#ifndef __gen_validate_value 46#define __gen_validate_value(x) 47#endif 48/* 49#ifndef __gen_address_type 50#error #define __gen_address_type before including this file 51#endif 52 53#ifndef __gen_user_data 54#error #define __gen_combine_address before including this file 55#endif 56*/ 57union __gen_value { 58 float f; 59 uint32_t dw; 60}; 61 62static inline uint64_t 63__gen_mbo(uint32_t start, uint32_t end) 64{ 65 return (~0ull >> (64 - (end - start + 1))) << start; 66} 67 68static inline uint64_t 69__gen_uint(uint64_t v, uint32_t start, uint32_t end) 70{ 71 __gen_validate_value(v); 72 73#ifndef NDEBUG 74 const int width = end - start + 1; 75 if (width < 64) { 76 const uint64_t max = (1ull << width) - 1; 77 assert(v <= max); 78 } 79#endif 80 81 return v << start; 82} 83 84static inline uint64_t 85__gen_sint(int64_t v, uint32_t start, uint32_t end) 86{ 87 const int width = end - start + 1; 88 89 __gen_validate_value(v); 90 91#ifndef NDEBUG 92 if (width < 64) { 93 const int64_t max = (1ll << (width - 1)) - 1; 94 const int64_t min = -(1ll << (width - 1)); 95 assert(min <= v && v <= max); 96 } 97#endif 98 99 const uint64_t mask = ~0ull >> (64 - width); 100 101 return (v & mask) << start; 102} 103 104static inline uint64_t 105__gen_offset(uint64_t v, uint32_t start, uint32_t end) 106{ 107 __gen_validate_value(v); 108#ifndef NDEBUG 109 uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start; 110 111 assert((v & ~mask) == 0); 112#endif 113 114 return v; 115} 116 117static inline uint32_t 118__gen_float(float v) 119{ 120 __gen_validate_value(v); 121 return ((union __gen_value) { .f = (v) }).dw; 122} 123 124static inline uint64_t 125__gen_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits) 126{ 127 __gen_validate_value(v); 128 129 const float factor = (1 << fract_bits); 130 131#ifndef NDEBUG 132 const float max = ((1 << (end - start)) - 1) / factor; 133 const float min = -(1 << (end - start)) / factor; 134 assert(min <= v && v <= max); 135#endif 136 137 const int64_t int_val = llroundf(v * factor); 138 const uint64_t mask = ~0ull >> (64 - (end - start + 1)); 139 140 return (int_val & mask) << start; 141} 142 143static inline uint64_t 144__gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits) 145{ 146 __gen_validate_value(v); 147 148 const float factor = (1 << fract_bits); 149 150#ifndef NDEBUG 151 const float max = ((1 << (end - start + 1)) - 1) / factor; 152 const float min = 0.0f; 153 assert(min <= v && v <= max); 154#endif 155 156 const uint64_t uint_val = llroundf(v * factor); 157 158 return uint_val << start; 159} 160 161static inline uint64_t 162__gen_unpack_uint(const uint8_t *restrict cl, uint32_t start, uint32_t end) 163{ 164 uint64_t val = 0; 165 const int width = end - start + 1; 166 const uint32_t mask = (width == 32 ? ~0 : (1 << width) - 1 ); 167 168 for (uint32_t byte = start / 8; byte <= end / 8; byte++) { 169 val |= cl[byte] << ((byte - start / 8) * 8); 170 } 171 172 return (val >> (start % 8)) & mask; 173} 174 175static inline uint64_t 176__gen_unpack_sint(const uint8_t *restrict cl, uint32_t start, uint32_t end) 177{ 178 int size = end - start + 1; 179 int64_t val = __gen_unpack_uint(cl, start, end); 180 181 /* Get the sign bit extended. */ 182 return (val << (64 - size)) >> (64 - size); 183} 184 185static inline float 186__gen_unpack_sfixed(const uint8_t *restrict cl, uint32_t start, uint32_t end, 187 uint32_t fractional_size) 188{ 189 int32_t bits = __gen_unpack_sint(cl, start, end); 190 return (float)bits / (1 << fractional_size); 191} 192 193static inline float 194__gen_unpack_ufixed(const uint8_t *restrict cl, uint32_t start, uint32_t end, 195 uint32_t fractional_size) 196{ 197 int32_t bits = __gen_unpack_uint(cl, start, end); 198 return (float)bits / (1 << fractional_size); 199} 200 201static inline float 202__gen_unpack_float(const uint8_t *restrict cl, uint32_t start, uint32_t end) 203{ 204 assert(start % 8 == 0); 205 assert(end - start == 31); 206 207 struct PACKED { float f; } *f = (void *)(cl + (start / 8)); 208 209 return f->f; 210} 211 212static inline float 213__gen_unpack_f187(const uint8_t *restrict cl, uint32_t start, uint32_t end) 214{ 215 assert(end - start == 15); 216 uint32_t bits = __gen_unpack_uint(cl, start, end); 217 return uif(bits << 16); 218} 219 220#endif 221