Merge pull request #107452 from Ivorforce/bit-math-header
Move binary math functions to `Math` namespace in `math_funcs_binary.h`
This commit is contained in:
commit
fa56f71ddd
50 changed files with 330 additions and 286 deletions
|
|
@ -425,7 +425,7 @@ class CharBuffer {
|
|||
int64_t written = 0;
|
||||
|
||||
bool grow() {
|
||||
if (vector.resize(next_power_of_2((uint64_t)1 + (uint64_t)written)) != OK) {
|
||||
if (vector.resize(Math::next_power_of_2((uint64_t)1 + (uint64_t)written)) != OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ bool FileAccessCompressed::store_buffer(const uint8_t *p_src, uint64_t p_length)
|
|||
write_max = write_pos + (p_length);
|
||||
}
|
||||
if (write_max > write_buffer_size) {
|
||||
write_buffer_size = next_power_of_2(write_max);
|
||||
write_buffer_size = Math::next_power_of_2(write_max);
|
||||
ERR_FAIL_COND_V(buffer.resize(write_buffer_size) != OK, false);
|
||||
write_ptr = buffer.ptrw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1231,14 +1231,14 @@ static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst,
|
|||
}
|
||||
|
||||
bool Image::is_size_po2() const {
|
||||
return is_power_of_2(width) && is_power_of_2(height);
|
||||
return Math::is_power_of_2(width) && Math::is_power_of_2(height);
|
||||
}
|
||||
|
||||
void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) {
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats.");
|
||||
|
||||
int w = next_power_of_2((uint32_t)width);
|
||||
int h = next_power_of_2((uint32_t)height);
|
||||
int w = Math::next_power_of_2((uint32_t)width);
|
||||
int h = Math::next_power_of_2((uint32_t)height);
|
||||
if (p_square) {
|
||||
w = h = MAX(w, h);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
|
||||
ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes");
|
||||
ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB");
|
||||
encode_buffer_max_size = next_power_of_2((uint32_t)p_max_size);
|
||||
encode_buffer_max_size = Math::next_power_of_2((uint32_t)p_max_size);
|
||||
encode_buffer.clear();
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
|
|||
|
||||
if (unlikely(encode_buffer.size() < len)) {
|
||||
encode_buffer.resize(0); // Avoid realloc
|
||||
encode_buffer.resize(next_power_of_2((uint32_t)len));
|
||||
encode_buffer.resize(Math::next_power_of_2((uint32_t)len));
|
||||
}
|
||||
|
||||
uint8_t *w = encode_buffer.ptrw();
|
||||
|
|
@ -301,8 +301,8 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
|
|||
ERR_FAIL_COND_MSG(p_max_size < 0, "Max size of input buffer size cannot be smaller than 0.");
|
||||
// WARNING: May lose packets.
|
||||
ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data.");
|
||||
ring_buffer.resize(nearest_shift(next_power_of_2((uint32_t)p_max_size + (uint32_t)4)) - 1);
|
||||
input_buffer.resize(next_power_of_2((uint32_t)p_max_size + (uint32_t)4));
|
||||
ring_buffer.resize(Math::nearest_shift(Math::next_power_of_2((uint32_t)p_max_size + (uint32_t)4)) - 1);
|
||||
input_buffer.resize(Math::next_power_of_2((uint32_t)p_max_size + (uint32_t)4));
|
||||
}
|
||||
|
||||
int PacketPeerStream::get_input_buffer_max_size() const {
|
||||
|
|
@ -310,7 +310,7 @@ int PacketPeerStream::get_input_buffer_max_size() const {
|
|||
}
|
||||
|
||||
void PacketPeerStream::set_output_buffer_max_size(int p_max_size) {
|
||||
output_buffer.resize(next_power_of_2((uint32_t)p_max_size + (uint32_t)4));
|
||||
output_buffer.resize(Math::next_power_of_2((uint32_t)p_max_size + (uint32_t)4));
|
||||
}
|
||||
|
||||
int PacketPeerStream::get_output_buffer_max_size() const {
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ Error PacketPeerUDP::bind(int p_port, const IPAddress &p_bind_address, int p_rec
|
|||
_sock->close();
|
||||
return err;
|
||||
}
|
||||
rb.resize(nearest_shift((uint32_t)p_recv_buffer_size));
|
||||
rb.resize(Math::nearest_shift((uint32_t)p_recv_buffer_size));
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ Error StreamPeerGZIP::_start(bool p_compress, bool p_is_deflate, int buffer_size
|
|||
ERR_FAIL_COND_V_MSG(buffer_size <= 0, ERR_INVALID_PARAMETER, "Invalid buffer size. It should be a positive integer.");
|
||||
clear();
|
||||
compressing = p_compress;
|
||||
rb.resize(nearest_shift(uint32_t(buffer_size - 1)));
|
||||
rb.resize(Math::nearest_shift(uint32_t(buffer_size - 1)));
|
||||
buffer.resize(1024);
|
||||
|
||||
// Create ctx.
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "geometry_2d.h"
|
||||
|
||||
#include "core/math/math_funcs_binary.h"
|
||||
|
||||
GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Walloc-zero")
|
||||
#include "thirdparty/clipper2/include/clipper2/clipper.h"
|
||||
GODOT_GCC_WARNING_POP
|
||||
|
|
@ -227,8 +229,8 @@ void Geometry2D::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_re
|
|||
real_t best_aspect = 1e20;
|
||||
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
real_t h = next_power_of_2((uint32_t)results[i].max_h);
|
||||
real_t w = next_power_of_2((uint32_t)results[i].max_w);
|
||||
real_t h = Math::next_power_of_2((uint32_t)results[i].max_h);
|
||||
real_t w = Math::next_power_of_2((uint32_t)results[i].max_w);
|
||||
real_t aspect = h > w ? h / w : w / h;
|
||||
if (aspect < best_aspect) {
|
||||
best = i;
|
||||
|
|
|
|||
188
core/math/math_funcs_binary.h
Normal file
188
core/math/math_funcs_binary.h
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/**************************************************************************/
|
||||
/* math_funcs_binary.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/typedefs.h"
|
||||
|
||||
namespace Math {
|
||||
|
||||
/* Functions to handle powers of 2 and shifting. */
|
||||
|
||||
// Returns `true` if a positive integer is a power of 2, `false` otherwise.
|
||||
template <typename T>
|
||||
inline bool is_power_of_2(const T x) {
|
||||
return x && ((x & (x - 1)) == 0);
|
||||
}
|
||||
|
||||
// Function to find the next power of 2 to an integer.
|
||||
constexpr uint64_t next_power_of_2(uint64_t p_number) {
|
||||
if (p_number == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
--p_number;
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
p_number |= p_number >> 32;
|
||||
|
||||
return ++p_number;
|
||||
}
|
||||
|
||||
constexpr uint32_t next_power_of_2(uint32_t p_number) {
|
||||
if (p_number == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
--p_number;
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
|
||||
return ++p_number;
|
||||
}
|
||||
|
||||
// Function to find the previous power of 2 to an integer.
|
||||
constexpr uint64_t previous_power_of_2(uint64_t p_number) {
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
p_number |= p_number >> 32;
|
||||
return p_number - (p_number >> 1);
|
||||
}
|
||||
|
||||
constexpr uint32_t previous_power_of_2(uint32_t p_number) {
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
return p_number - (p_number >> 1);
|
||||
}
|
||||
|
||||
// Function to find the closest power of 2 to an integer.
|
||||
constexpr uint64_t closest_power_of_2(uint64_t p_number) {
|
||||
uint64_t nx = next_power_of_2(p_number);
|
||||
uint64_t px = previous_power_of_2(p_number);
|
||||
return (nx - p_number) > (p_number - px) ? px : nx;
|
||||
}
|
||||
|
||||
constexpr uint32_t closest_power_of_2(uint32_t p_number) {
|
||||
uint32_t nx = next_power_of_2(p_number);
|
||||
uint32_t px = previous_power_of_2(p_number);
|
||||
return (nx - p_number) > (p_number - px) ? px : nx;
|
||||
}
|
||||
|
||||
// Get a shift value from a power of 2.
|
||||
constexpr int32_t get_shift_from_power_of_2(uint64_t p_bits) {
|
||||
for (uint64_t i = 0; i < (uint64_t)64; i++) {
|
||||
if (p_bits == (uint64_t)((uint64_t)1 << i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int32_t get_shift_from_power_of_2(uint32_t p_bits) {
|
||||
for (uint32_t i = 0; i < (uint32_t)32; i++) {
|
||||
if (p_bits == (uint32_t)((uint32_t)1 << i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ T nearest_power_of_2_templated(T p_number) {
|
||||
--p_number;
|
||||
|
||||
// The number of operations on x is the base two logarithm
|
||||
// of the number of bits in the type. Add three to account
|
||||
// for sizeof(T) being in bytes.
|
||||
constexpr size_t shift_steps = get_shift_from_power_of_2((uint64_t)sizeof(T)) + 3;
|
||||
|
||||
// If the compiler is smart, it unrolls this loop.
|
||||
// If it's dumb, this is a bit slow.
|
||||
for (size_t i = 0; i < shift_steps; i++) {
|
||||
p_number |= p_number >> (1 << i);
|
||||
}
|
||||
|
||||
return ++p_number;
|
||||
}
|
||||
|
||||
// Function to find the nearest (bigger) power of 2 to an integer.
|
||||
constexpr uint64_t nearest_shift(uint64_t p_number) {
|
||||
uint64_t i = 63;
|
||||
do {
|
||||
i--;
|
||||
if (p_number & ((uint64_t)1 << i)) {
|
||||
return i + (uint64_t)1;
|
||||
}
|
||||
} while (i != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
constexpr uint32_t nearest_shift(uint32_t p_number) {
|
||||
uint32_t i = 31;
|
||||
do {
|
||||
i--;
|
||||
if (p_number & ((uint32_t)1 << i)) {
|
||||
return i + (uint32_t)1;
|
||||
}
|
||||
} while (i != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// constexpr function to find the floored log2 of a number
|
||||
template <typename T>
|
||||
constexpr T floor_log2(T x) {
|
||||
return x < 2 ? x : 1 + floor_log2(x >> 1);
|
||||
}
|
||||
|
||||
// Get the number of bits needed to represent the number.
|
||||
// IE, if you pass in 8, you will get 4.
|
||||
// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1).
|
||||
template <typename T>
|
||||
constexpr T get_num_bits(T x) {
|
||||
return floor_log2(x);
|
||||
}
|
||||
|
||||
} //namespace Math
|
||||
|
|
@ -2258,8 +2258,8 @@ void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindi
|
|||
}
|
||||
}
|
||||
if (unlikely(!binding && p_callbacks)) {
|
||||
uint32_t current_size = next_power_of_2(_instance_binding_count);
|
||||
uint32_t new_size = next_power_of_2(_instance_binding_count + 1);
|
||||
uint32_t current_size = Math::next_power_of_2(_instance_binding_count);
|
||||
uint32_t new_size = Math::next_power_of_2(_instance_binding_count + 1);
|
||||
|
||||
if (current_size == 0 || new_size > current_size) {
|
||||
_instance_bindings = (InstanceBinding *)memrealloc(_instance_bindings, new_size * sizeof(InstanceBinding));
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "memory.h"
|
||||
|
||||
#include "core/math/math_funcs_binary.h"
|
||||
#include "core/profiling/profiling.h"
|
||||
#include "core/templates/safe_refcount.h"
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ static SafeNumeric<uint64_t> _max_mem_usage;
|
|||
#endif
|
||||
|
||||
void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) {
|
||||
DEV_ASSERT(is_power_of_2(p_alignment));
|
||||
DEV_ASSERT(Math::is_power_of_2(p_alignment));
|
||||
|
||||
void *p1, *p2;
|
||||
if ((p1 = (void *)malloc(p_bytes + p_alignment - 1 + sizeof(uint32_t))) == nullptr) {
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::reserve(int p_
|
|||
}
|
||||
|
||||
bool need_copy = string_length > 0 && buffer.is_empty();
|
||||
buffer.resize_uninitialized(next_power_of_2((uint32_t)p_size));
|
||||
buffer.resize_uninitialized(Math::next_power_of_2((uint32_t)p_size));
|
||||
if (need_copy) {
|
||||
memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(char32_t));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/math/math_funcs_binary.h"
|
||||
#include "core/os/memory.h"
|
||||
#include "core/string/print_string.h"
|
||||
#include "core/templates/hashfuncs.h"
|
||||
|
|
@ -210,7 +211,7 @@ private:
|
|||
uint32_t real_old_capacity = _capacity_mask + 1;
|
||||
// Capacity can't be 0 and must be 2^n - 1.
|
||||
_capacity_mask = MAX(4u, p_new_capacity);
|
||||
uint32_t real_capacity = next_power_of_2(_capacity_mask);
|
||||
uint32_t real_capacity = Math::next_power_of_2(_capacity_mask);
|
||||
_capacity_mask = real_capacity - 1;
|
||||
|
||||
Metadata *old_map_data = _metadata;
|
||||
|
|
@ -412,7 +413,7 @@ public:
|
|||
void reserve(uint32_t p_new_capacity) {
|
||||
if (_elements == nullptr) {
|
||||
_capacity_mask = MAX(4u, p_new_capacity);
|
||||
_capacity_mask = next_power_of_2(_capacity_mask) - 1;
|
||||
_capacity_mask = Math::next_power_of_2(_capacity_mask) - 1;
|
||||
return; // Unallocated yet.
|
||||
}
|
||||
if (p_new_capacity <= get_capacity()) {
|
||||
|
|
@ -690,7 +691,7 @@ public:
|
|||
AHashMap(uint32_t p_initial_capacity) {
|
||||
// Capacity can't be 0 and must be 2^n - 1.
|
||||
_capacity_mask = MAX(4u, p_initial_capacity);
|
||||
_capacity_mask = next_power_of_2(_capacity_mask) - 1;
|
||||
_capacity_mask = Math::next_power_of_2(_capacity_mask) - 1;
|
||||
}
|
||||
AHashMap() :
|
||||
_capacity_mask(INITIAL_CAPACITY - 1) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/core_globals.h"
|
||||
#include "core/math/math_funcs_binary.h"
|
||||
#include "core/os/memory.h"
|
||||
#include "core/os/spin_lock.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
|
@ -145,9 +146,9 @@ public:
|
|||
}
|
||||
ERR_FAIL_COND(page_pool != nullptr); // Safety check.
|
||||
ERR_FAIL_COND(p_page_size == 0);
|
||||
page_size = nearest_power_of_2_templated(p_page_size);
|
||||
page_size = Math::nearest_power_of_2_templated(p_page_size);
|
||||
page_mask = page_size - 1;
|
||||
page_shift = get_shift_from_power_of_2(page_size);
|
||||
page_shift = Math::get_shift_from_power_of_2(page_size);
|
||||
if constexpr (thread_safe) {
|
||||
spin_lock.unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/math/math_funcs_binary.h"
|
||||
#include "core/os/memory.h"
|
||||
#include "core/os/spin_lock.h"
|
||||
#include "core/typedefs.h"
|
||||
|
|
@ -88,7 +89,7 @@ public:
|
|||
}
|
||||
|
||||
uint32_t get_page_size_shift() const {
|
||||
return get_shift_from_power_of_2(page_size);
|
||||
return Math::get_shift_from_power_of_2(page_size);
|
||||
}
|
||||
|
||||
uint32_t get_page_size_mask() const {
|
||||
|
|
@ -116,7 +117,7 @@ public:
|
|||
void configure(uint32_t p_page_size) {
|
||||
ERR_FAIL_COND(page_pool != nullptr); // Safety check.
|
||||
ERR_FAIL_COND(p_page_size == 0);
|
||||
page_size = nearest_power_of_2_templated(p_page_size);
|
||||
page_size = Math::nearest_power_of_2_templated(p_page_size);
|
||||
}
|
||||
|
||||
PagedArrayPool(uint32_t p_page_size = 4096) { // power of 2 recommended because of alignment with OS page sizes. Even if element is bigger, its still a multiple and get rounded amount of pages
|
||||
|
|
|
|||
159
core/typedefs.h
159
core/typedefs.h
|
|
@ -140,167 +140,16 @@ constexpr auto CLAMP(const T m_a, const T2 m_min, const T3 m_max) {
|
|||
return m_a < m_min ? m_min : (m_a > m_max ? m_max : m_a);
|
||||
}
|
||||
|
||||
// Generic swap template.
|
||||
#ifndef SWAP
|
||||
#define SWAP(m_x, m_y) std::swap((m_x), (m_y))
|
||||
#endif // SWAP
|
||||
|
||||
// Like std::size, but without requiring any additional includes.
|
||||
template <typename T, size_t SIZE>
|
||||
constexpr size_t std_size(const T (&)[SIZE]) {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
/* Functions to handle powers of 2 and shifting. */
|
||||
|
||||
// Returns `true` if a positive integer is a power of 2, `false` otherwise.
|
||||
template <typename T>
|
||||
inline bool is_power_of_2(const T x) {
|
||||
return x && ((x & (x - 1)) == 0);
|
||||
}
|
||||
|
||||
// Function to find the next power of 2 to an integer.
|
||||
constexpr uint64_t next_power_of_2(uint64_t p_number) {
|
||||
if (p_number == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
--p_number;
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
p_number |= p_number >> 32;
|
||||
|
||||
return ++p_number;
|
||||
}
|
||||
|
||||
constexpr uint32_t next_power_of_2(uint32_t p_number) {
|
||||
if (p_number == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
--p_number;
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
|
||||
return ++p_number;
|
||||
}
|
||||
|
||||
// Function to find the previous power of 2 to an integer.
|
||||
constexpr uint64_t previous_power_of_2(uint64_t p_number) {
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
p_number |= p_number >> 32;
|
||||
return p_number - (p_number >> 1);
|
||||
}
|
||||
|
||||
constexpr uint32_t previous_power_of_2(uint32_t p_number) {
|
||||
p_number |= p_number >> 1;
|
||||
p_number |= p_number >> 2;
|
||||
p_number |= p_number >> 4;
|
||||
p_number |= p_number >> 8;
|
||||
p_number |= p_number >> 16;
|
||||
return p_number - (p_number >> 1);
|
||||
}
|
||||
|
||||
// Function to find the closest power of 2 to an integer.
|
||||
constexpr uint64_t closest_power_of_2(uint64_t p_number) {
|
||||
uint64_t nx = next_power_of_2(p_number);
|
||||
uint64_t px = previous_power_of_2(p_number);
|
||||
return (nx - p_number) > (p_number - px) ? px : nx;
|
||||
}
|
||||
|
||||
constexpr uint32_t closest_power_of_2(uint32_t p_number) {
|
||||
uint32_t nx = next_power_of_2(p_number);
|
||||
uint32_t px = previous_power_of_2(p_number);
|
||||
return (nx - p_number) > (p_number - px) ? px : nx;
|
||||
}
|
||||
|
||||
// Get a shift value from a power of 2.
|
||||
constexpr int32_t get_shift_from_power_of_2(uint64_t p_bits) {
|
||||
for (uint64_t i = 0; i < (uint64_t)64; i++) {
|
||||
if (p_bits == (uint64_t)((uint64_t)1 << i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int32_t get_shift_from_power_of_2(uint32_t p_bits) {
|
||||
for (uint32_t i = 0; i < (uint32_t)32; i++) {
|
||||
if (p_bits == (uint32_t)((uint32_t)1 << i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static _FORCE_INLINE_ T nearest_power_of_2_templated(T p_number) {
|
||||
--p_number;
|
||||
|
||||
// The number of operations on x is the base two logarithm
|
||||
// of the number of bits in the type. Add three to account
|
||||
// for sizeof(T) being in bytes.
|
||||
constexpr size_t shift_steps = get_shift_from_power_of_2((uint64_t)sizeof(T)) + 3;
|
||||
|
||||
// If the compiler is smart, it unrolls this loop.
|
||||
// If it's dumb, this is a bit slow.
|
||||
for (size_t i = 0; i < shift_steps; i++) {
|
||||
p_number |= p_number >> (1 << i);
|
||||
}
|
||||
|
||||
return ++p_number;
|
||||
}
|
||||
|
||||
// Function to find the nearest (bigger) power of 2 to an integer.
|
||||
constexpr uint64_t nearest_shift(uint64_t p_number) {
|
||||
uint64_t i = 63;
|
||||
do {
|
||||
i--;
|
||||
if (p_number & ((uint64_t)1 << i)) {
|
||||
return i + (uint64_t)1;
|
||||
}
|
||||
} while (i != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
constexpr uint32_t nearest_shift(uint32_t p_number) {
|
||||
uint32_t i = 31;
|
||||
do {
|
||||
i--;
|
||||
if (p_number & ((uint32_t)1 << i)) {
|
||||
return i + (uint32_t)1;
|
||||
}
|
||||
} while (i != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// constexpr function to find the floored log2 of a number
|
||||
template <typename T>
|
||||
constexpr T floor_log2(T x) {
|
||||
return x < 2 ? x : 1 + floor_log2(x >> 1);
|
||||
}
|
||||
|
||||
// Get the number of bits needed to represent the number.
|
||||
// IE, if you pass in 8, you will get 4.
|
||||
// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1).
|
||||
template <typename T>
|
||||
constexpr T get_num_bits(T x) {
|
||||
return floor_log2(x);
|
||||
}
|
||||
// Generic swap template.
|
||||
#ifndef SWAP
|
||||
#define SWAP(m_x, m_y) std::swap((m_x), (m_y))
|
||||
#endif // SWAP
|
||||
|
||||
// Swap 16, 32 and 64 bits value for endianness.
|
||||
#if defined(__GNUC__)
|
||||
|
|
|
|||
|
|
@ -769,7 +769,7 @@ int64_t VariantUtilityFunctions::clampi(int64_t x, int64_t min, int64_t max) {
|
|||
}
|
||||
|
||||
int64_t VariantUtilityFunctions::nearest_po2(int64_t x) {
|
||||
return nearest_power_of_2_templated(uint64_t(x));
|
||||
return Math::nearest_power_of_2_templated(uint64_t(x));
|
||||
}
|
||||
|
||||
// Random
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ Error AudioDriverALSA::init_output_device() {
|
|||
// Ref: https://www.alsa-project.org/main/index.php/FramesPeriods
|
||||
unsigned int periods = 2;
|
||||
int latency = Engine::get_singleton()->get_audio_output_latency();
|
||||
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
|
||||
buffer_frames = Math::closest_power_of_2(latency * mix_rate / 1000);
|
||||
buffer_size = buffer_frames * periods;
|
||||
period_size = buffer_frames;
|
||||
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ Error AudioDriverCoreAudio::init() {
|
|||
|
||||
uint32_t latency = Engine::get_singleton()->get_audio_output_latency();
|
||||
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
|
||||
buffer_frames = closest_power_of_2(latency * (uint32_t)mix_rate / (uint32_t)1000);
|
||||
buffer_frames = Math::closest_power_of_2(latency * (uint32_t)mix_rate / (uint32_t)1000);
|
||||
|
||||
#ifdef MACOS_ENABLED
|
||||
result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
|
||||
|
|
@ -461,7 +461,7 @@ Error AudioDriverCoreAudio::init_input_device() {
|
|||
|
||||
uint32_t latency = Engine::get_singleton()->get_audio_output_latency();
|
||||
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
|
||||
capture_buffer_frames = closest_power_of_2(latency * (uint32_t)capture_mix_rate / (uint32_t)1000);
|
||||
capture_buffer_frames = Math::closest_power_of_2(latency * (uint32_t)capture_mix_rate / (uint32_t)1000);
|
||||
|
||||
buffer_size = capture_buffer_frames * capture_channels;
|
||||
|
||||
|
|
|
|||
|
|
@ -1119,7 +1119,7 @@ uint32_t RenderingDeviceDriverD3D12::_find_max_common_supported_sample_count(Vec
|
|||
msql.SampleCount = (UINT)samples;
|
||||
HRESULT res = device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msql, sizeof(msql));
|
||||
if (SUCCEEDED(res) && msql.NumQualityLevels) {
|
||||
int bit = get_shift_from_power_of_2((uint32_t)samples);
|
||||
int bit = Math::get_shift_from_power_of_2((uint32_t)samples);
|
||||
ERR_FAIL_COND_V(bit == -1, 1);
|
||||
mask |= (uint32_t)(1 << bit);
|
||||
}
|
||||
|
|
@ -1131,7 +1131,7 @@ uint32_t RenderingDeviceDriverD3D12::_find_max_common_supported_sample_count(Vec
|
|||
if (common == UINT32_MAX) {
|
||||
return 1;
|
||||
} else {
|
||||
return ((uint32_t)1 << nearest_shift(common));
|
||||
return ((uint32_t)1 << Math::nearest_shift(common));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2161,7 +2161,7 @@ void RasterizerCanvasGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::C
|
|||
|
||||
void RasterizerCanvasGLES3::set_shadow_texture_size(int p_size) {
|
||||
GLES3::Config *config = GLES3::Config::get_singleton();
|
||||
p_size = nearest_power_of_2_templated(p_size);
|
||||
p_size = Math::nearest_power_of_2_templated(p_size);
|
||||
|
||||
if (p_size > config->max_texture_size) {
|
||||
p_size = config->max_texture_size;
|
||||
|
|
|
|||
|
|
@ -1285,7 +1285,7 @@ void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits
|
|||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_NULL(shadow_atlas);
|
||||
ERR_FAIL_COND(p_size < 0);
|
||||
p_size = next_power_of_2((uint32_t)p_size);
|
||||
p_size = Math::next_power_of_2((uint32_t)p_size);
|
||||
|
||||
if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
|
||||
return;
|
||||
|
|
@ -1332,7 +1332,7 @@ void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quad
|
|||
ERR_FAIL_INDEX(p_quadrant, 4);
|
||||
ERR_FAIL_INDEX(p_subdivision, 16384);
|
||||
|
||||
uint32_t subdiv = next_power_of_2((uint32_t)p_subdivision);
|
||||
uint32_t subdiv = Math::next_power_of_2((uint32_t)p_subdivision);
|
||||
if (subdiv & 0xaaaaaaaa) { // sqrt(subdiv) must be integer.
|
||||
subdiv <<= 1;
|
||||
}
|
||||
|
|
@ -1406,7 +1406,7 @@ bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_instance,
|
|||
}
|
||||
|
||||
uint32_t quad_size = shadow_atlas->size >> 1;
|
||||
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(uint32_t(quad_size * p_coverage)));
|
||||
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, Math::next_power_of_2(uint32_t(quad_size * p_coverage)));
|
||||
|
||||
int valid_quadrants[4];
|
||||
int valid_quadrant_count = 0;
|
||||
|
|
@ -1675,7 +1675,7 @@ void LightStorage::update_directional_shadow_atlas() {
|
|||
}
|
||||
|
||||
void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
|
||||
p_size = nearest_power_of_2_templated(p_size);
|
||||
p_size = Math::nearest_power_of_2_templated(p_size);
|
||||
|
||||
if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2356,7 +2356,7 @@ void TextureStorage::update_texture_atlas() {
|
|||
si.pixel_size = Size2i(src_tex->width, src_tex->height);
|
||||
|
||||
if (base_size < (uint32_t)si.size.width) {
|
||||
base_size = nearest_power_of_2_templated(si.size.width);
|
||||
base_size = Math::nearest_power_of_2_templated(si.size.width);
|
||||
}
|
||||
|
||||
si.texture = E.key;
|
||||
|
|
@ -2426,7 +2426,7 @@ void TextureStorage::update_texture_atlas() {
|
|||
}
|
||||
|
||||
texture_atlas.size.width = base_size * border;
|
||||
texture_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
|
||||
texture_atlas.size.height = Math::nearest_power_of_2_templated(atlas_height * border);
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
TextureAtlas::Texture *t = texture_atlas.textures.getptr(items[i].texture);
|
||||
|
|
@ -3598,7 +3598,7 @@ void TextureStorage::render_target_sdf_process(RID p_render_target) {
|
|||
|
||||
// Process
|
||||
|
||||
int stride = nearest_power_of_2_templated(MAX(size.width, size.height) / 2);
|
||||
int stride = Math::nearest_power_of_2_templated(MAX(size.width, size.height) / 2);
|
||||
|
||||
variant = CanvasSdfShaderGLES3::MODE_PROCESS;
|
||||
success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ Error AudioDriverPulseAudio::init_output_device() {
|
|||
}
|
||||
|
||||
int tmp_latency = Engine::get_singleton()->get_audio_output_latency();
|
||||
buffer_frames = closest_power_of_2(tmp_latency * mix_rate / 1000);
|
||||
buffer_frames = Math::closest_power_of_2(tmp_latency * mix_rate / 1000);
|
||||
pa_buffer_size = buffer_frames * pa_map.channels;
|
||||
|
||||
print_verbose("PulseAudio: detected " + itos(pa_map.channels) + " output channels");
|
||||
|
|
@ -727,7 +727,7 @@ Error AudioDriverPulseAudio::init_input_device() {
|
|||
spec.rate = mix_rate;
|
||||
|
||||
int input_latency = 30;
|
||||
int input_buffer_frames = closest_power_of_2(input_latency * mix_rate / 1000);
|
||||
int input_buffer_frames = Math::closest_power_of_2(input_latency * mix_rate / 1000);
|
||||
int input_buffer_size = input_buffer_frames * spec.channels;
|
||||
|
||||
pa_buffer_attr attr = {};
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ Error AudioDriverXAudio2::init() {
|
|||
channels = 2;
|
||||
|
||||
int latency = Engine::get_singleton()->get_audio_output_latency();
|
||||
buffer_size = closest_power_of_2(latency * mix_rate / 1000);
|
||||
buffer_size = Math::closest_power_of_2(latency * mix_rate / 1000);
|
||||
|
||||
samples_in = memnew_arr(int32_t, size_t(buffer_size) * channels);
|
||||
for (int i = 0; i < AUDIO_BUFFERS; i++) {
|
||||
|
|
|
|||
|
|
@ -171,8 +171,8 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
|
|||
|
||||
bitmaps.sort();
|
||||
|
||||
int atlas_max_width = nearest_power_of_2_templated(p_atlas_max_size) / divide_by;
|
||||
int atlas_w = nearest_power_of_2_templated(max_w);
|
||||
int atlas_max_width = Math::nearest_power_of_2_templated(p_atlas_max_size) / divide_by;
|
||||
int atlas_w = Math::nearest_power_of_2_templated(max_w);
|
||||
int atlas_h;
|
||||
while (true) {
|
||||
atlas_h = 0;
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ void Texture3DEditor::_update_gui() {
|
|||
}
|
||||
|
||||
const uint32_t components_mask = Image::get_format_component_mask(format);
|
||||
if (is_power_of_2(components_mask)) {
|
||||
if (Math::is_power_of_2(components_mask)) {
|
||||
// Only one channel available, no point in showing a channel selector.
|
||||
channel_selector->hide();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
|
|||
const uint32_t components_mask = format != Image::FORMAT_MAX ? Image::get_format_component_mask(format) : 0xf;
|
||||
|
||||
// Add color channel selector at the bottom left if more than 1 channel is available.
|
||||
if (p_show_metadata && !is_power_of_2(components_mask)) {
|
||||
if (p_show_metadata && !Math::is_power_of_2(components_mask)) {
|
||||
channel_selector = memnew(ColorChannelSelector);
|
||||
channel_selector->connect("selected_channels_changed", callable_mp(this, &TexturePreview::on_selected_channels_changed));
|
||||
channel_selector->set_h_size_flags(Control::SIZE_SHRINK_BEGIN);
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ void TextureLayeredEditor::_update_gui() {
|
|||
info->set_text(texture_info);
|
||||
|
||||
const uint32_t components_mask = Image::get_format_component_mask(format);
|
||||
if (is_power_of_2(components_mask)) {
|
||||
if (Math::is_power_of_2(components_mask)) {
|
||||
// Only one channel available, no point in showing a channel selector.
|
||||
channel_selector->hide();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ void LightmapperRD::_sort_triangle_clusters(uint32_t p_cluster_size, uint32_t p_
|
|||
break;
|
||||
}
|
||||
|
||||
uint32_t left_cluster_count = next_power_of_2(p_count / 2);
|
||||
uint32_t left_cluster_count = Math::next_power_of_2(p_count / 2);
|
||||
left_cluster_count = MAX(left_cluster_count, p_cluster_size);
|
||||
left_cluster_count = MIN(left_cluster_count, p_count);
|
||||
_sort_triangle_clusters(p_cluster_size, p_cluster_index, p_index_start, left_cluster_count, p_triangle_sort, p_cluster_aabb);
|
||||
|
|
@ -257,8 +257,8 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
|
|||
atlas_size = atlas_size.max(s + Size2i(2, 2).maxi(p_denoiser_range) * p_supersampling_factor);
|
||||
}
|
||||
|
||||
int max = nearest_power_of_2_templated(atlas_size.width);
|
||||
max = MAX(max, nearest_power_of_2_templated(atlas_size.height));
|
||||
int max = Math::nearest_power_of_2_templated(atlas_size.width);
|
||||
max = MAX(max, Math::nearest_power_of_2_templated(atlas_size.height));
|
||||
|
||||
if (max > p_max_texture_size) {
|
||||
return BAKE_ERROR_TEXTURE_EXCEEDS_MAX_SIZE;
|
||||
|
|
@ -1016,7 +1016,7 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref<RDSh
|
|||
// We denoise in fixed size regions and synchronize execution to avoid GPU timeouts.
|
||||
// We use a region with 1/4 the amount of pixels if we're denoising SH lightmaps, as
|
||||
// all four of them are denoised in the shader in one dispatch.
|
||||
const int user_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
|
||||
const int user_region_size = Math::nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
|
||||
const int max_region_size = p_bake_sh ? user_region_size / 2 : user_region_size;
|
||||
int x_regions = Math::division_round_up(p_atlas_size.width, max_region_size);
|
||||
int y_regions = Math::division_round_up(p_atlas_size.height, max_region_size);
|
||||
|
|
@ -1683,7 +1683,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
|
|||
}
|
||||
}
|
||||
|
||||
const int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
|
||||
const int max_region_size = Math::nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
|
||||
const int x_regions = Math::division_round_up(atlas_size.width, max_region_size);
|
||||
const int y_regions = Math::division_round_up(atlas_size.height, max_region_size);
|
||||
|
||||
|
|
|
|||
|
|
@ -870,17 +870,17 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
|
|||
// Could not find texture to fit, create one.
|
||||
int texsize = MAX(p_data->size.x * 0.125, 256);
|
||||
|
||||
texsize = next_power_of_2((uint32_t)texsize);
|
||||
texsize = Math::next_power_of_2((uint32_t)texsize);
|
||||
if (p_msdf) {
|
||||
texsize = MIN(texsize, 2048);
|
||||
} else {
|
||||
texsize = MIN(texsize, 1024);
|
||||
}
|
||||
if (mw > texsize) { // Special case, adapt to it?
|
||||
texsize = next_power_of_2((uint32_t)mw);
|
||||
texsize = Math::next_power_of_2((uint32_t)mw);
|
||||
}
|
||||
if (mh > texsize) { // Special case, adapt to it?
|
||||
texsize = next_power_of_2((uint32_t)mh);
|
||||
texsize = Math::next_power_of_2((uint32_t)mh);
|
||||
}
|
||||
|
||||
ShelfPackTexture tex = ShelfPackTexture(texsize, texsize);
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_
|
|||
// Could not find texture to fit, create one.
|
||||
int texsize = MAX(p_data->size.x * 0.125, 256);
|
||||
|
||||
texsize = next_power_of_2((uint32_t)texsize);
|
||||
texsize = Math::next_power_of_2((uint32_t)texsize);
|
||||
|
||||
if (p_msdf) {
|
||||
texsize = MIN(texsize, 2048);
|
||||
|
|
@ -295,10 +295,10 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_
|
|||
texsize = MIN(texsize, 1024);
|
||||
}
|
||||
if (mw > texsize) { // Special case, adapt to it?
|
||||
texsize = next_power_of_2((uint32_t)mw);
|
||||
texsize = Math::next_power_of_2((uint32_t)mw);
|
||||
}
|
||||
if (mh > texsize) { // Special case, adapt to it?
|
||||
texsize = next_power_of_2((uint32_t)mh);
|
||||
texsize = Math::next_power_of_2((uint32_t)mh);
|
||||
}
|
||||
|
||||
ShelfPackTexture tex = ShelfPackTexture(texsize, texsize);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ void WebRTCDataChannel::_bind_methods() {
|
|||
}
|
||||
|
||||
WebRTCDataChannel::WebRTCDataChannel() {
|
||||
_in_buffer_shift = nearest_shift(uint32_t((int)GLOBAL_GET("network/limits/webrtc/max_channel_in_buffer_kb") - 1)) + (uint32_t)10;
|
||||
_in_buffer_shift = Math::nearest_shift(uint32_t((int)GLOBAL_GET("network/limits/webrtc/max_channel_in_buffer_kb") - 1)) + (uint32_t)10;
|
||||
}
|
||||
|
||||
WebRTCDataChannel::~WebRTCDataChannel() {
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ Error EMWSPeer::connect_to_url(const String &p_url, const Ref<TLSOptions> &p_tls
|
|||
if (peer_sock == -1) {
|
||||
return FAILED;
|
||||
}
|
||||
in_buffer.resize(nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets);
|
||||
in_buffer.resize(Math::nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets);
|
||||
packet_buffer.resize(inbound_buffer_size);
|
||||
ready_state = STATE_CONNECTING;
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ Error WSLPeer::_do_server_handshake() {
|
|||
wslay_event_context_server_init(&wsl_ctx, &_wsl_callbacks, this);
|
||||
wslay_event_config_set_no_buffering(wsl_ctx, 1);
|
||||
wslay_event_config_set_max_recv_msg_length(wsl_ctx, inbound_buffer_size);
|
||||
in_buffer.resize(nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets);
|
||||
in_buffer.resize(Math::nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets);
|
||||
packet_buffer.resize(inbound_buffer_size);
|
||||
ready_state = STATE_OPEN;
|
||||
}
|
||||
|
|
@ -406,7 +406,7 @@ void WSLPeer::_do_client_handshake() {
|
|||
wslay_event_context_client_init(&wsl_ctx, &_wsl_callbacks, this);
|
||||
wslay_event_config_set_no_buffering(wsl_ctx, 1);
|
||||
wslay_event_config_set_max_recv_msg_length(wsl_ctx, inbound_buffer_size);
|
||||
in_buffer.resize(nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets);
|
||||
in_buffer.resize(Math::nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets);
|
||||
packet_buffer.resize(inbound_buffer_size);
|
||||
ready_state = STATE_OPEN;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ Error AudioDriverWeb::init() {
|
|||
}
|
||||
mix_rate = audio_context.mix_rate;
|
||||
channel_count = audio_context.channel_count;
|
||||
buffer_length = closest_power_of_2(uint32_t(latency * mix_rate / 1000));
|
||||
buffer_length = Math::closest_power_of_2(uint32_t(latency * mix_rate / 1000));
|
||||
Error err = create(buffer_length, channel_count);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -4578,7 +4578,7 @@ struct AnimationCompressionDataState {
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
return nearest_shift((uint32_t)p_delta);
|
||||
return Math::nearest_shift((uint32_t)p_delta);
|
||||
}
|
||||
|
||||
void _compute_max_shifts(uint32_t p_from, uint32_t p_to, uint32_t *max_shifts, uint32_t &max_frame_delta_shift) const {
|
||||
|
|
@ -4589,7 +4589,7 @@ struct AnimationCompressionDataState {
|
|||
|
||||
for (uint32_t i = p_from + 1; i <= p_to; i++) {
|
||||
int32_t frame_delta = temp_packets[i].frame - temp_packets[i - 1].frame;
|
||||
max_frame_delta_shift = MAX(max_frame_delta_shift, nearest_shift((uint32_t)frame_delta));
|
||||
max_frame_delta_shift = MAX(max_frame_delta_shift, Math::nearest_shift((uint32_t)frame_delta));
|
||||
for (uint32_t j = 0; j < components; j++) {
|
||||
int32_t diff = _compute_delta16_signed(temp_packets[i - 1].data[j], temp_packets[i].data[j]);
|
||||
uint32_t shift = _compute_shift_bits_signed(diff);
|
||||
|
|
|
|||
|
|
@ -357,27 +357,27 @@ public:
|
|||
private:
|
||||
struct MaterialKey {
|
||||
// enum values
|
||||
uint64_t texture_filter : get_num_bits(TEXTURE_FILTER_MAX - 1);
|
||||
uint64_t detail_uv : get_num_bits(DETAIL_UV_MAX - 1);
|
||||
uint64_t transparency : get_num_bits(TRANSPARENCY_MAX - 1);
|
||||
uint64_t alpha_antialiasing_mode : get_num_bits(ALPHA_ANTIALIASING_MAX - 1);
|
||||
uint64_t shading_mode : get_num_bits(SHADING_MODE_MAX - 1);
|
||||
uint64_t blend_mode : get_num_bits(BLEND_MODE_MAX - 1);
|
||||
uint64_t depth_draw_mode : get_num_bits(DEPTH_DRAW_MAX - 1);
|
||||
uint64_t depth_test : get_num_bits(DEPTH_TEST_MAX - 1);
|
||||
uint64_t cull_mode : get_num_bits(CULL_MAX - 1);
|
||||
uint64_t diffuse_mode : get_num_bits(DIFFUSE_MAX - 1);
|
||||
uint64_t specular_mode : get_num_bits(SPECULAR_MAX - 1);
|
||||
uint64_t billboard_mode : get_num_bits(BILLBOARD_MAX - 1);
|
||||
uint64_t detail_blend_mode : get_num_bits(BLEND_MODE_MAX - 1);
|
||||
uint64_t roughness_channel : get_num_bits(TEXTURE_CHANNEL_MAX - 1);
|
||||
uint64_t emission_op : get_num_bits(EMISSION_OP_MAX - 1);
|
||||
uint64_t distance_fade : get_num_bits(DISTANCE_FADE_MAX - 1);
|
||||
uint64_t texture_filter : Math::get_num_bits(TEXTURE_FILTER_MAX - 1);
|
||||
uint64_t detail_uv : Math::get_num_bits(DETAIL_UV_MAX - 1);
|
||||
uint64_t transparency : Math::get_num_bits(TRANSPARENCY_MAX - 1);
|
||||
uint64_t alpha_antialiasing_mode : Math::get_num_bits(ALPHA_ANTIALIASING_MAX - 1);
|
||||
uint64_t shading_mode : Math::get_num_bits(SHADING_MODE_MAX - 1);
|
||||
uint64_t blend_mode : Math::get_num_bits(BLEND_MODE_MAX - 1);
|
||||
uint64_t depth_draw_mode : Math::get_num_bits(DEPTH_DRAW_MAX - 1);
|
||||
uint64_t depth_test : Math::get_num_bits(DEPTH_TEST_MAX - 1);
|
||||
uint64_t cull_mode : Math::get_num_bits(CULL_MAX - 1);
|
||||
uint64_t diffuse_mode : Math::get_num_bits(DIFFUSE_MAX - 1);
|
||||
uint64_t specular_mode : Math::get_num_bits(SPECULAR_MAX - 1);
|
||||
uint64_t billboard_mode : Math::get_num_bits(BILLBOARD_MAX - 1);
|
||||
uint64_t detail_blend_mode : Math::get_num_bits(BLEND_MODE_MAX - 1);
|
||||
uint64_t roughness_channel : Math::get_num_bits(TEXTURE_CHANNEL_MAX - 1);
|
||||
uint64_t emission_op : Math::get_num_bits(EMISSION_OP_MAX - 1);
|
||||
uint64_t distance_fade : Math::get_num_bits(DISTANCE_FADE_MAX - 1);
|
||||
|
||||
// stencil
|
||||
uint64_t stencil_mode : get_num_bits(STENCIL_MODE_MAX - 1);
|
||||
uint64_t stencil_mode : Math::get_num_bits(STENCIL_MODE_MAX - 1);
|
||||
uint64_t stencil_flags : STENCIL_FLAG_NUM_BITS;
|
||||
uint64_t stencil_compare : get_num_bits(STENCIL_COMPARE_MAX - 1);
|
||||
uint64_t stencil_compare : Math::get_num_bits(STENCIL_COMPARE_MAX - 1);
|
||||
uint64_t stencil_reference : 8;
|
||||
|
||||
// booleans
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "audio_rb_resampler.h"
|
||||
|
||||
#include "core/math/audio_frame.h"
|
||||
#include "core/math/math_funcs_binary.h"
|
||||
#include "core/os/memory.h"
|
||||
|
||||
int AudioRBResampler::get_channel_count() const {
|
||||
|
|
@ -178,7 +179,7 @@ int AudioRBResampler::get_num_of_ready_frames() {
|
|||
Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed) {
|
||||
ERR_FAIL_COND_V(p_channels != 1 && p_channels != 2 && p_channels != 4 && p_channels != 6 && p_channels != 8, ERR_INVALID_PARAMETER);
|
||||
|
||||
int desired_rb_bits = nearest_shift((uint32_t)MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed));
|
||||
int desired_rb_bits = Math::nearest_shift((uint32_t)MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed));
|
||||
|
||||
bool recreate = !rb;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ Ref<AudioEffectInstance> AudioEffectCapture::instantiate() {
|
|||
if (!buffer_initialized) {
|
||||
float target_buffer_size = AudioServer::get_singleton()->get_mix_rate() * buffer_length_seconds;
|
||||
ERR_FAIL_COND_V(target_buffer_size <= 0 || target_buffer_size >= (1 << 27), Ref<AudioEffectInstance>());
|
||||
buffer.resize(nearest_shift((uint32_t)target_buffer_size));
|
||||
buffer.resize(Math::nearest_shift((uint32_t)target_buffer_size));
|
||||
buffer_initialized = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ Ref<AudioStreamPlayback> AudioStreamGenerator::instantiate_playback() {
|
|||
playback.instantiate();
|
||||
playback->generator = this;
|
||||
uint32_t target_buffer_size = _get_target_rate() * buffer_len;
|
||||
playback->buffer.resize(nearest_shift(target_buffer_size));
|
||||
playback->buffer.resize(Math::nearest_shift(target_buffer_size));
|
||||
playback->buffer.clear();
|
||||
return playback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ void ClusterBuilderRD::bake_cluster() {
|
|||
|
||||
RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection);
|
||||
state.inv_z_far = 1.0 / z_far;
|
||||
state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);
|
||||
state.screen_to_clusters_shift = Math::get_shift_from_power_of_2(cluster_size);
|
||||
state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less
|
||||
|
||||
state.cluster_screen_width = cluster_screen_size.x;
|
||||
|
|
@ -600,7 +600,7 @@ void ClusterBuilderRD::debug(ElementType p_element) {
|
|||
push_constant.screen_size[1] = screen_size.y;
|
||||
push_constant.cluster_screen_size[0] = cluster_screen_size.x;
|
||||
push_constant.cluster_screen_size[1] = cluster_screen_size.y;
|
||||
push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size);
|
||||
push_constant.cluster_shift = Math::get_shift_from_power_of_2(cluster_size);
|
||||
push_constant.cluster_type = p_element;
|
||||
push_constant.orthogonal = camera_orthogonal;
|
||||
push_constant.z_far = z_far;
|
||||
|
|
|
|||
|
|
@ -1127,7 +1127,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
|
|||
|
||||
{
|
||||
uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size();
|
||||
params.cluster_shift = get_shift_from_power_of_2(cluster_size);
|
||||
params.cluster_shift = Math::get_shift_from_power_of_2(cluster_size);
|
||||
|
||||
uint32_t cluster_screen_width = Math::division_round_up((uint32_t)p_settings.rb_size.x, cluster_size);
|
||||
uint32_t cluster_screen_height = Math::division_round_up((uint32_t)p_settings.rb_size.y, cluster_size);
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re
|
|||
RD::TextureFormat tf_aniso1 = tf_sdf;
|
||||
tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM;
|
||||
|
||||
int passes = nearest_shift(cascade_size) - 1;
|
||||
int passes = Math::nearest_shift(cascade_size) - 1;
|
||||
|
||||
//store lightprobe SH
|
||||
RD::TextureFormat tf_probes;
|
||||
|
|
@ -2659,7 +2659,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
|
|||
|
||||
{
|
||||
uint32_t dynamic_map_size = MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
|
||||
uint32_t oversample = nearest_power_of_2_templated(4);
|
||||
uint32_t oversample = Math::nearest_power_of_2_templated(4);
|
||||
int mipmap_index = 0;
|
||||
|
||||
while (mipmap_index < mipmaps.size()) {
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ uint32_t RenderForwardClustered::_setup_environment(const RenderDataRD *p_render
|
|||
|
||||
// now do implementation UBO
|
||||
|
||||
scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_render_data->cluster_size);
|
||||
scene_state.ubo.cluster_shift = Math::get_shift_from_power_of_2(p_render_data->cluster_size);
|
||||
scene_state.ubo.max_cluster_element_count_div_32 = p_render_data->cluster_max_elements / 32;
|
||||
{
|
||||
uint32_t cluster_screen_width = Math::division_round_up((uint32_t)p_screen_size.width, p_render_data->cluster_size);
|
||||
|
|
@ -789,7 +789,7 @@ void RenderForwardClustered::SceneState::grow_instance_buffer(RenderListType p_r
|
|||
if (p_req_element_count > 0) {
|
||||
if (instance_buffer[p_render_list].get_size(0u) < p_req_element_count * sizeof(SceneState::InstanceData)) {
|
||||
instance_buffer[p_render_list].uninit();
|
||||
uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count));
|
||||
uint32_t new_size = Math::nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count));
|
||||
instance_buffer[p_render_list].set_storage_size(0u, new_size * sizeof(SceneState::InstanceData));
|
||||
curr_gpu_ptr[p_render_list] = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1960,7 +1960,7 @@ void RenderForwardMobile::SceneState::grow_instance_buffer(RenderListType p_rend
|
|||
if (p_req_element_count > 0) {
|
||||
if (instance_buffer[p_render_list].get_size(0u) < p_req_element_count * sizeof(SceneState::InstanceData)) {
|
||||
instance_buffer[p_render_list].uninit();
|
||||
uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count));
|
||||
uint32_t new_size = Math::nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count));
|
||||
instance_buffer[p_render_list].set_storage_size(0u, new_size * sizeof(SceneState::InstanceData));
|
||||
curr_gpu_ptr[p_render_list] = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1002,7 +1002,7 @@ void RendererCanvasRenderRD::_update_occluder_buffer(uint32_t p_size) {
|
|||
|
||||
if (p_size > state.shadow_occluder_buffer_size) {
|
||||
needs_update = true;
|
||||
state.shadow_occluder_buffer_size = next_power_of_2(p_size);
|
||||
state.shadow_occluder_buffer_size = Math::next_power_of_2(p_size);
|
||||
if (state.shadow_occluder_buffer.is_valid()) {
|
||||
RD::get_singleton()->free_rid(state.shadow_occluder_buffer);
|
||||
}
|
||||
|
|
@ -2146,7 +2146,7 @@ bool RendererCanvasRenderRD::free(RID p_rid) {
|
|||
}
|
||||
|
||||
void RendererCanvasRenderRD::set_shadow_texture_size(int p_size) {
|
||||
p_size = MAX(1, nearest_power_of_2_templated(p_size));
|
||||
p_size = MAX(1, Math::nearest_power_of_2_templated(p_size));
|
||||
if (p_size == state.shadow_texture_size) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2157,7 +2157,7 @@ void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits
|
|||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_NULL(shadow_atlas);
|
||||
ERR_FAIL_COND(p_size < 0);
|
||||
p_size = next_power_of_2((uint32_t)p_size);
|
||||
p_size = Math::next_power_of_2((uint32_t)p_size);
|
||||
|
||||
if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
|
||||
return;
|
||||
|
|
@ -2194,7 +2194,7 @@ void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quad
|
|||
ERR_FAIL_INDEX(p_quadrant, 4);
|
||||
ERR_FAIL_INDEX(p_subdivision, 16384);
|
||||
|
||||
uint32_t subdiv = next_power_of_2((uint32_t)p_subdivision);
|
||||
uint32_t subdiv = Math::next_power_of_2((uint32_t)p_subdivision);
|
||||
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
|
||||
subdiv <<= 1;
|
||||
}
|
||||
|
|
@ -2389,7 +2389,7 @@ bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_instance,
|
|||
}
|
||||
|
||||
uint32_t quad_size = shadow_atlas->size >> 1;
|
||||
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(uint32_t(quad_size * p_coverage)));
|
||||
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, Math::next_power_of_2(uint32_t(quad_size * p_coverage)));
|
||||
|
||||
int valid_quadrants[4];
|
||||
int valid_quadrant_count = 0;
|
||||
|
|
@ -2554,7 +2554,7 @@ void LightStorage::update_directional_shadow_atlas() {
|
|||
}
|
||||
}
|
||||
void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
|
||||
p_size = nearest_power_of_2_templated(p_size);
|
||||
p_size = Math::nearest_power_of_2_templated(p_size);
|
||||
|
||||
if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -3431,7 +3431,7 @@ void TextureStorage::update_decal_atlas() {
|
|||
si.pixel_size = Size2i(src_tex->width, src_tex->height);
|
||||
|
||||
if (base_size < (uint32_t)si.size.width) {
|
||||
base_size = nearest_power_of_2_templated(si.size.width);
|
||||
base_size = Math::nearest_power_of_2_templated(si.size.width);
|
||||
}
|
||||
|
||||
si.texture = E.key;
|
||||
|
|
@ -3501,7 +3501,7 @@ void TextureStorage::update_decal_atlas() {
|
|||
}
|
||||
|
||||
decal_atlas.size.width = base_size * border;
|
||||
decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
|
||||
decal_atlas.size.height = Math::nearest_power_of_2_templated(atlas_height * border);
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
|
||||
|
|
@ -4678,7 +4678,7 @@ void TextureStorage::render_target_sdf_process(RID p_render_target) {
|
|||
|
||||
/* Process */
|
||||
|
||||
int stride = nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2);
|
||||
int stride = Math::nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[RenderTargetSDF::SHADER_PROCESS]);
|
||||
|
||||
|
|
|
|||
|
|
@ -6540,7 +6540,7 @@ RenderingDevice::TransferWorker *RenderingDevice::_acquire_transfer_worker(uint3
|
|||
driver->buffer_free(transfer_worker->staging_buffer);
|
||||
}
|
||||
|
||||
uint32_t new_staging_buffer_size = next_power_of_2(expected_buffer_size);
|
||||
uint32_t new_staging_buffer_size = Math::next_power_of_2(expected_buffer_size);
|
||||
transfer_worker->staging_buffer_size_allocated = new_staging_buffer_size;
|
||||
transfer_worker->staging_buffer = driver->buffer_create(new_staging_buffer_size, RDD::BUFFER_USAGE_TRANSFER_FROM_BIT, RDD::MEMORY_ALLOCATION_TYPE_CPU, frames_drawn);
|
||||
}
|
||||
|
|
@ -7807,10 +7807,10 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ
|
|||
download_staging_buffers.max_size = upload_staging_buffers.max_size;
|
||||
|
||||
texture_upload_region_size_px = GLOBAL_GET("rendering/rendering_device/staging_buffer/texture_upload_region_size_px");
|
||||
texture_upload_region_size_px = nearest_power_of_2_templated(texture_upload_region_size_px);
|
||||
texture_upload_region_size_px = Math::nearest_power_of_2_templated(texture_upload_region_size_px);
|
||||
|
||||
texture_download_region_size_px = GLOBAL_GET("rendering/rendering_device/staging_buffer/texture_download_region_size_px");
|
||||
texture_download_region_size_px = nearest_power_of_2_templated(texture_download_region_size_px);
|
||||
texture_download_region_size_px = Math::nearest_power_of_2_templated(texture_download_region_size_px);
|
||||
|
||||
// Ensure current staging block is valid and at least one per frame exists.
|
||||
upload_staging_buffers.current = 0;
|
||||
|
|
|
|||
|
|
@ -58,35 +58,35 @@ TEST_CASE("[Math] C++ macros") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Math] Power of two functions") {
|
||||
CHECK(next_power_of_2((uint32_t)0) == 0);
|
||||
CHECK(next_power_of_2((uint32_t)1) == 1);
|
||||
CHECK(next_power_of_2((uint32_t)16) == 16);
|
||||
CHECK(next_power_of_2((uint32_t)17) == 32);
|
||||
CHECK(next_power_of_2((uint32_t)65535) == 65536);
|
||||
CHECK(Math::next_power_of_2((uint32_t)0) == 0);
|
||||
CHECK(Math::next_power_of_2((uint32_t)1) == 1);
|
||||
CHECK(Math::next_power_of_2((uint32_t)16) == 16);
|
||||
CHECK(Math::next_power_of_2((uint32_t)17) == 32);
|
||||
CHECK(Math::next_power_of_2((uint32_t)65535) == 65536);
|
||||
|
||||
CHECK(previous_power_of_2((uint32_t)0) == 0);
|
||||
CHECK(previous_power_of_2((uint32_t)1) == 1);
|
||||
CHECK(previous_power_of_2((uint32_t)16) == 16);
|
||||
CHECK(previous_power_of_2((uint32_t)17) == 16);
|
||||
CHECK(previous_power_of_2((uint32_t)65535) == 32768);
|
||||
CHECK(Math::previous_power_of_2((uint32_t)0) == 0);
|
||||
CHECK(Math::previous_power_of_2((uint32_t)1) == 1);
|
||||
CHECK(Math::previous_power_of_2((uint32_t)16) == 16);
|
||||
CHECK(Math::previous_power_of_2((uint32_t)17) == 16);
|
||||
CHECK(Math::previous_power_of_2((uint32_t)65535) == 32768);
|
||||
|
||||
CHECK(closest_power_of_2((uint32_t)0) == 0);
|
||||
CHECK(closest_power_of_2((uint32_t)1) == 1);
|
||||
CHECK(closest_power_of_2((uint32_t)16) == 16);
|
||||
CHECK(closest_power_of_2((uint32_t)17) == 16);
|
||||
CHECK(closest_power_of_2((uint32_t)65535) == 65536);
|
||||
CHECK(Math::closest_power_of_2((uint32_t)0) == 0);
|
||||
CHECK(Math::closest_power_of_2((uint32_t)1) == 1);
|
||||
CHECK(Math::closest_power_of_2((uint32_t)16) == 16);
|
||||
CHECK(Math::closest_power_of_2((uint32_t)17) == 16);
|
||||
CHECK(Math::closest_power_of_2((uint32_t)65535) == 65536);
|
||||
|
||||
CHECK(get_shift_from_power_of_2((uint32_t)0) == -1);
|
||||
CHECK(get_shift_from_power_of_2((uint32_t)1) == 0);
|
||||
CHECK(get_shift_from_power_of_2((uint32_t)16) == 4);
|
||||
CHECK(get_shift_from_power_of_2((uint32_t)17) == -1);
|
||||
CHECK(get_shift_from_power_of_2((uint32_t)65535) == -1);
|
||||
CHECK(Math::get_shift_from_power_of_2((uint32_t)0) == -1);
|
||||
CHECK(Math::get_shift_from_power_of_2((uint32_t)1) == 0);
|
||||
CHECK(Math::get_shift_from_power_of_2((uint32_t)16) == 4);
|
||||
CHECK(Math::get_shift_from_power_of_2((uint32_t)17) == -1);
|
||||
CHECK(Math::get_shift_from_power_of_2((uint32_t)65535) == -1);
|
||||
|
||||
CHECK(nearest_shift((uint32_t)0) == 0);
|
||||
CHECK(nearest_shift((uint32_t)1) == 1);
|
||||
CHECK(nearest_shift((uint32_t)16) == 5);
|
||||
CHECK(nearest_shift((uint32_t)17) == 5);
|
||||
CHECK(nearest_shift((uint32_t)65535) == 16);
|
||||
CHECK(Math::nearest_shift((uint32_t)0) == 0);
|
||||
CHECK(Math::nearest_shift((uint32_t)1) == 1);
|
||||
CHECK(Math::nearest_shift((uint32_t)16) == 5);
|
||||
CHECK(Math::nearest_shift((uint32_t)17) == 5);
|
||||
CHECK(Math::nearest_shift((uint32_t)65535) == 16);
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] abs", T, int, float, double) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue