mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-06 15:05:59 +00:00
gpu2: move shader resource management to cache
fixed descriptor set binding fixed 5_6_5 format swizzling fix rect calculation fix possible crash in scheduler implement lock-free bit pool utility
This commit is contained in:
parent
4e83c9e121
commit
0877d3f1cd
12 changed files with 1175 additions and 967 deletions
72
rx/include/rx/ConcurrentBitPool.hpp
Normal file
72
rx/include/rx/ConcurrentBitPool.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <bit>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace rx {
|
||||
namespace detail {
|
||||
template <std::size_t Count> auto pickBitSetBaseType() {
|
||||
if constexpr (Count <= 8) {
|
||||
return std::array<std::atomic<std::uint8_t>, 1>{};
|
||||
} else if constexpr (Count <= 16) {
|
||||
return std::array<std::atomic<std::uint16_t>, 1>{};
|
||||
} else if constexpr (Count <= 32) {
|
||||
return std::array<std::atomic<std::uint32_t>, 1>{};
|
||||
} else {
|
||||
return std::array<std::atomic<std::uint64_t>, (Count + 63) / 64>();
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t Count>
|
||||
using ConcurrentBitPoolBaseType = decltype(pickBitSetBaseType<Count>());
|
||||
} // namespace detail
|
||||
|
||||
template <std::size_t BitCount, typename ElementType = std::size_t>
|
||||
class ConcurrentBitPool {
|
||||
detail::ConcurrentBitPoolBaseType<BitCount> mStorage{{}};
|
||||
using WordType = std::remove_cvref_t<decltype(mStorage[0])>::value_type;
|
||||
static constexpr auto kWordBitWidth = sizeof(WordType) * 8;
|
||||
|
||||
public:
|
||||
ElementType acquire() {
|
||||
while (true) {
|
||||
for (auto &node : mStorage) {
|
||||
auto mask = node.load(std::memory_order::acquire);
|
||||
|
||||
auto bitIndex = std::countr_one(mask);
|
||||
if (bitIndex >= kWordBitWidth) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto pattern = static_cast<WordType>(1) << bitIndex;
|
||||
|
||||
if (!node.compare_exchange_strong(mask, mask | pattern,
|
||||
std::memory_order::release,
|
||||
std::memory_order::relaxed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto wordIndex = &node - mStorage.data();
|
||||
return static_cast<ElementType>(kWordBitWidth * wordIndex + bitIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void release(ElementType index) {
|
||||
auto rawIndex = static_cast<std::size_t>(index);
|
||||
auto bitIndex = rawIndex % kWordBitWidth;
|
||||
auto wordIndex = rawIndex / kWordBitWidth;
|
||||
|
||||
WordType pattern = static_cast<WordType>(1) << bitIndex;
|
||||
WordType mask = pattern;
|
||||
|
||||
while (!mStorage[wordIndex].compare_exchange_weak(
|
||||
mask, mask & ~pattern, std::memory_order::release,
|
||||
std::memory_order::acquire)) {
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace rx
|
||||
Loading…
Add table
Add a link
Reference in a new issue