1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00

rsx: refactor rsx_utils a bit

- Move obviously standalone things to their own utility files
This commit is contained in:
kd-11 2021-09-17 23:01:53 +03:00 committed by kd-11
parent 7f830d555d
commit 7b9fb7ad9c
14 changed files with 432 additions and 389 deletions

View File

@ -0,0 +1,93 @@
#pragma once
#include <util/types.hpp>
#include <bitset>
namespace rsx
{
template <int N>
void unpack_bitset(const std::bitset<N>& block, u64* values)
{
for (int bit = 0, n = -1, shift = 0; bit < N; ++bit, ++shift)
{
if ((bit % 64) == 0)
{
values[++n] = 0;
shift = 0;
}
if (block[bit])
{
values[n] |= (1ull << shift);
}
}
}
template <int N>
void pack_bitset(std::bitset<N>& block, u64* values)
{
for (int n = 0, shift = 0; shift < N; ++n, shift += 64)
{
std::bitset<N> tmp = values[n];
tmp <<= shift;
block |= tmp;
}
}
template <typename T, typename bitmask_type = u32>
class atomic_bitmask_t
{
private:
atomic_t<bitmask_type> m_data{ 0 };
public:
atomic_bitmask_t() = default;
T load() const
{
return static_cast<T>(m_data.load());
}
void store(T value)
{
m_data.store(static_cast<bitmask_type>(value));
}
bool operator & (T mask) const
{
return ((m_data.load() & static_cast<bitmask_type>(mask)) != 0);
}
T operator | (T mask) const
{
return static_cast<T>(m_data.load() | static_cast<bitmask_type>(mask));
}
void operator &= (T mask)
{
m_data.fetch_and(static_cast<bitmask_type>(mask));
}
void operator |= (T mask)
{
m_data.fetch_or(static_cast<bitmask_type>(mask));
}
bool test_and_set(T mask)
{
const auto old = m_data.fetch_or(static_cast<bitmask_type>(mask));
return (old & static_cast<bitmask_type>(mask)) != 0;
}
auto clear(T mask)
{
bitmask_type clear_mask = ~(static_cast<bitmask_type>(mask));
return m_data.and_fetch(clear_mask);
}
void clear()
{
m_data.store(0);
}
};
}

View File

@ -0,0 +1,34 @@
#pragma once
#include <util/types.hpp>
namespace rsx
{
struct profiling_timer
{
bool enabled = false;
steady_clock::time_point last;
profiling_timer() = default;
void start()
{
if (enabled) [[unlikely]]
{
last = steady_clock::now();
}
}
s64 duration()
{
if (!enabled) [[likely]]
{
return 0ll;
}
auto old = last;
last = steady_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(last - old).count();
}
};
}

View File

@ -0,0 +1,278 @@
#pragma once
#include <util/types.hpp>
namespace rsx
{
template <typename Ty>
struct simple_array
{
public:
using iterator = Ty*;
using const_iterator = const Ty*;
using value_type = Ty;
private:
u32 _capacity = 0;
u32 _size = 0;
Ty* _data = nullptr;
inline u64 offset(const_iterator pos)
{
return (_data) ? u64(pos - _data) : 0ull;
}
public:
simple_array() = default;
simple_array(u32 initial_size, const Ty val = {})
{
reserve(initial_size);
_size = initial_size;
for (u32 n = 0; n < initial_size; ++n)
{
_data[n] = val;
}
}
simple_array(const std::initializer_list<Ty>& args)
{
reserve(::size32(args));
for (const auto& arg : args)
{
push_back(arg);
}
}
simple_array(const simple_array& other)
{
_capacity = other._capacity;
_size = other._size;
const auto size_bytes = sizeof(Ty) * _capacity;
_data = static_cast<Ty*>(malloc(size_bytes));
std::memcpy(_data, other._data, size_bytes);
}
simple_array(simple_array&& other) noexcept
{
swap(other);
}
simple_array& operator=(const simple_array& other)
{
if (&other != this)
{
simple_array{ other }.swap(*this);
}
return *this;
}
simple_array& operator=(simple_array&& other) noexcept
{
swap(other);
return *this;
}
~simple_array()
{
if (_data)
{
free(_data);
_data = nullptr;
_size = _capacity = 0;
}
}
void swap(simple_array<Ty>& other) noexcept
{
std::swap(_capacity, other._capacity);
std::swap(_size, other._size);
std::swap(_data, other._data);
}
void reserve(u32 size)
{
if (_capacity >= size)
return;
ensure(_data = static_cast<Ty*>(std::realloc(_data, sizeof(Ty) * size))); // "realloc() failed!"
_capacity = size;
}
void resize(u32 size)
{
reserve(size);
_size = size;
}
void push_back(const Ty& val)
{
if (_size >= _capacity)
{
reserve(_capacity + 16);
}
_data[_size++] = val;
}
void push_back(Ty&& val)
{
if (_size >= _capacity)
{
reserve(_capacity + 16);
}
_data[_size++] = val;
}
Ty pop_back()
{
return _data[--_size];
}
iterator insert(iterator pos, const Ty& val)
{
ensure(pos >= _data);
const auto _loc = offset(pos);
if (_size >= _capacity)
{
reserve(_capacity + 16);
pos = _data + _loc;
}
if (_loc >= _size)
{
_data[_size++] = val;
return pos;
}
ensure(_loc < _size);
const auto remaining = (_size - _loc);
memmove(pos + 1, pos, remaining * sizeof(Ty));
*pos = val;
_size++;
return pos;
}
iterator insert(iterator pos, Ty&& val)
{
ensure(pos >= _data);
const auto _loc = offset(pos);
if (_size >= _capacity)
{
reserve(_capacity + 16);
pos = _data + _loc;
}
if (_loc >= _size)
{
_data[_size++] = val;
return pos;
}
ensure(_loc < _size);
const u32 remaining = (_size - _loc);
memmove(pos + 1, pos, remaining * sizeof(Ty));
*pos = val;
_size++;
return pos;
}
void clear()
{
_size = 0;
}
bool empty() const
{
return _size == 0;
}
u32 size() const
{
return _size;
}
u64 size_bytes() const
{
return _size * sizeof(Ty);
}
u32 capacity() const
{
return _capacity;
}
Ty& operator[] (u32 index)
{
return _data[index];
}
const Ty& operator[] (u32 index) const
{
return _data[index];
}
Ty* data()
{
return _data;
}
const Ty* data() const
{
return _data;
}
Ty& back()
{
return _data[_size - 1];
}
const Ty& back() const
{
return _data[_size - 1];
}
Ty& front()
{
return _data[0];
}
const Ty& front() const
{
return _data[0];
}
iterator begin()
{
return _data;
}
iterator end()
{
return _data ? _data + _size : nullptr;
}
const_iterator begin() const
{
return _data;
}
const_iterator end() const
{
return _data ? _data + _size : nullptr;
}
};
}

View File

@ -1,9 +1,9 @@
#pragma once
#include "util/types.hpp"
#include "../Common/simple_array.hpp"
#include "../Overlays/overlays.h"
#include "GLTexture.h"
#include "Emu/RSX/rsx_utils.h"
#include <string>
#include <unordered_map>

View File

@ -3,7 +3,6 @@
#include "Common/BufferUtils.h"
#include "RSXOffload.h"
#include "RSXThread.h"
#include "rsx_utils.h"
#include <thread>
#include "util/asm.hpp"

View File

@ -9,7 +9,6 @@
#include "Common/surface_store.h"
#include "Capture/rsx_capture.h"
#include "rsx_methods.h"
#include "rsx_utils.h"
#include "gcm_printing.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/lv2/sys_time.h"

View File

@ -12,6 +12,8 @@
#include "RSXFIFO.h"
#include "RSXOffload.h"
#include "rsx_utils.h"
#include "Common/bitfield.hpp"
#include "Common/profiling_timer.hpp"
#include "Common/texture_cache_types.h"
#include "Program/RSXVertexProgram.h"
#include "Program/RSXFragmentProgram.h"

View File

@ -1,6 +1,8 @@
#pragma once
#include "../Common/simple_array.hpp"
#include "../Overlays/overlay_controls.h"
#include "VKProgramPipeline.h"
#include "VKHelpers.h"

View File

@ -2,13 +2,13 @@
#include "Utilities/File.h"
#include "Utilities/lockless.h"
#include "Utilities/Thread.h"
#include "Program/ProgramStateCache.h"
#include "Common/bitfield.hpp"
#include "Emu/System.h"
#include "Emu/cache_utils.hpp"
#include "Program/ProgramStateCache.h"
#include "Common/texture_cache_checker.h"
#include "Overlays/Shaders/shader_loading_dialog.h"
#include "rsx_utils.h"
#include <chrono>
#include <unordered_map>

View File

@ -6,7 +6,7 @@
#include "rsx_decode.h"
#include "RSXTexture.h"
#include "rsx_vertex_data.h"
#include "rsx_utils.h"
#include "Common/simple_array.hpp"
#include "Emu/Cell/timers.hpp"
#include "Program/program_util.h"

View File

@ -851,380 +851,4 @@ namespace rsx
return base * scale;
}
template <int N>
void unpack_bitset(const std::bitset<N>& block, u64* values)
{
for (int bit = 0, n = -1, shift = 0; bit < N; ++bit, ++shift)
{
if ((bit % 64) == 0)
{
values[++n] = 0;
shift = 0;
}
if (block[bit])
{
values[n] |= (1ull << shift);
}
}
}
template <int N>
void pack_bitset(std::bitset<N>& block, u64* values)
{
for (int n = 0, shift = 0; shift < N; ++n, shift += 64)
{
std::bitset<N> tmp = values[n];
tmp <<= shift;
block |= tmp;
}
}
template <typename T, typename bitmask_type = u32>
class atomic_bitmask_t
{
private:
atomic_t<bitmask_type> m_data{0};
public:
atomic_bitmask_t() = default;
T load() const
{
return static_cast<T>(m_data.load());
}
void store(T value)
{
m_data.store(static_cast<bitmask_type>(value));
}
bool operator & (T mask) const
{
return ((m_data.load() & static_cast<bitmask_type>(mask)) != 0);
}
T operator | (T mask) const
{
return static_cast<T>(m_data.load() | static_cast<bitmask_type>(mask));
}
void operator &= (T mask)
{
m_data.fetch_and(static_cast<bitmask_type>(mask));
}
void operator |= (T mask)
{
m_data.fetch_or(static_cast<bitmask_type>(mask));
}
bool test_and_set(T mask)
{
const auto old = m_data.fetch_or(static_cast<bitmask_type>(mask));
return (old & static_cast<bitmask_type>(mask)) != 0;
}
auto clear(T mask)
{
bitmask_type clear_mask = ~(static_cast<bitmask_type>(mask));
return m_data.and_fetch(clear_mask);
}
void clear()
{
m_data.store(0);
}
};
template <typename Ty>
struct simple_array
{
public:
using iterator = Ty*;
using const_iterator = const Ty*;
using value_type = Ty;
private:
u32 _capacity = 0;
u32 _size = 0;
Ty* _data = nullptr;
inline u64 offset(const_iterator pos)
{
return (_data) ? u64(pos - _data) : 0ull;
}
public:
simple_array() = default;
simple_array(u32 initial_size, const Ty val = {})
{
reserve(initial_size);
_size = initial_size;
for (u32 n = 0; n < initial_size; ++n)
{
_data[n] = val;
}
}
simple_array(const std::initializer_list<Ty>& args)
{
reserve(::size32(args));
for (const auto& arg : args)
{
push_back(arg);
}
}
simple_array(const simple_array& other)
{
_capacity = other._capacity;
_size = other._size;
const auto size_bytes = sizeof(Ty) * _capacity;
_data = static_cast<Ty*>(malloc(size_bytes));
std::memcpy(_data, other._data, size_bytes);
}
simple_array(simple_array&& other) noexcept
{
swap(other);
}
simple_array& operator=(const simple_array& other)
{
if (&other != this)
{
simple_array{other}.swap(*this);
}
return *this;
}
simple_array& operator=(simple_array&& other) noexcept
{
swap(other);
return *this;
}
~simple_array()
{
if (_data)
{
free(_data);
_data = nullptr;
_size = _capacity = 0;
}
}
void swap(simple_array<Ty>& other) noexcept
{
std::swap(_capacity, other._capacity);
std::swap(_size, other._size);
std::swap(_data, other._data);
}
void reserve(u32 size)
{
if (_capacity >= size)
return;
ensure(_data = static_cast<Ty*>(std::realloc(_data, sizeof(Ty) * size))); // "realloc() failed!"
_capacity = size;
}
void resize(u32 size)
{
reserve(size);
_size = size;
}
void push_back(const Ty& val)
{
if (_size >= _capacity)
{
reserve(_capacity + 16);
}
_data[_size++] = val;
}
void push_back(Ty&& val)
{
if (_size >= _capacity)
{
reserve(_capacity + 16);
}
_data[_size++] = val;
}
iterator insert(iterator pos, const Ty& val)
{
ensure(pos >= _data);
const auto _loc = offset(pos);
if (_size >= _capacity)
{
reserve(_capacity + 16);
pos = _data + _loc;
}
if (_loc >= _size)
{
_data[_size++] = val;
return pos;
}
ensure(_loc < _size);
const auto remaining = (_size - _loc);
memmove(pos + 1, pos, remaining * sizeof(Ty));
*pos = val;
_size++;
return pos;
}
iterator insert(iterator pos, Ty&& val)
{
ensure(pos >= _data);
const auto _loc = offset(pos);
if (_size >= _capacity)
{
reserve(_capacity + 16);
pos = _data + _loc;
}
if (_loc >= _size)
{
_data[_size++] = val;
return pos;
}
ensure(_loc < _size);
const u32 remaining = (_size - _loc);
memmove(pos + 1, pos, remaining * sizeof(Ty));
*pos = val;
_size++;
return pos;
}
void clear()
{
_size = 0;
}
bool empty() const
{
return _size == 0;
}
u32 size() const
{
return _size;
}
u32 capacity() const
{
return _capacity;
}
Ty& operator[] (u32 index)
{
return _data[index];
}
const Ty& operator[] (u32 index) const
{
return _data[index];
}
Ty* data()
{
return _data;
}
const Ty* data() const
{
return _data;
}
Ty& back()
{
return _data[_size - 1];
}
const Ty& back() const
{
return _data[_size - 1];
}
Ty& front()
{
return _data[0];
}
const Ty& front() const
{
return _data[0];
}
iterator begin()
{
return _data;
}
iterator end()
{
return _data ? _data + _size : nullptr;
}
const_iterator begin() const
{
return _data;
}
const_iterator end() const
{
return _data ? _data + _size : nullptr;
}
};
struct profiling_timer
{
bool enabled = false;
steady_clock::time_point last;
profiling_timer() = default;
void start()
{
if (enabled) [[unlikely]]
{
last = steady_clock::now();
}
}
s64 duration()
{
if (!enabled) [[likely]]
{
return 0ll;
}
auto old = last;
last = steady_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(last - old).count();
}
};
}

View File

@ -2,8 +2,8 @@
#include "gcm_enums.h"
#include "Common/simple_array.hpp"
#include "util/types.hpp"
#include "rsx_utils.h"
namespace rsx
{

View File

@ -461,6 +461,9 @@
<ClInclude Include="Emu\NP\np_structs_extra.h" />
<ClInclude Include="Emu\NP\rpcn_client.h" />
<ClInclude Include="Emu\NP\rpcn_config.h" />
<ClInclude Include="Emu\RSX\Common\bitfield.hpp" />
<ClInclude Include="Emu\RSX\Common\profiling_timer.hpp" />
<ClInclude Include="Emu\RSX\Common\simple_array.hpp" />
<ClInclude Include="Emu\RSX\Overlays\overlay_edit_text.hpp" />
<ClInclude Include="Emu\RSX\Overlays\overlay_list_view.hpp" />
<ClInclude Include="Emu\RSX\Overlays\overlay_progress_bar.hpp" />

View File

@ -1990,6 +1990,15 @@
<ClInclude Include="Emu\vfs_config.h">
<Filter>Emu</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\Common\simple_array.hpp">
<Filter>Emu\GPU\RSX\Common</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\Common\profiling_timer.hpp">
<Filter>Emu\GPU\RSX\Common</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\Common\bitfield.hpp">
<Filter>Emu\GPU\RSX\Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Emu\RSX\Common\Interpreter\FragmentInterpreter.glsl">