Compare commits

...

20 Commits

Author SHA1 Message Date
Lioncash
6335bf136f service/hid: Amend forward declaration of ServiceManager
The SM namespace is within the Service namespace, so this was forward
declaring a type that didn't exist.
2019-02-27 11:36:48 -05:00
bunnei
42f7c11021 Merge pull request #2169 from lioncash/naming
audio_core/audio_renderer: Provide names for some parameters of AudioRendererParameter
2019-02-27 11:26:54 -05:00
bunnei
14430f7df9 Merge pull request #2170 from lioncash/emu-window
core/frontend/emu_window: Make ClipToTouchScreen a const member function
2019-02-27 11:26:24 -05:00
bunnei
eb5a3dd1c7 Merge pull request #2161 from lioncash/handle-table
kernel/handle_table: Allow process capabilities to limit the handle table size
2019-02-27 11:22:26 -05:00
bunnei
be1a1584fc Merge pull request #2168 from lioncash/cubeb
externals: Update cubeb to the master version
2019-02-27 11:20:14 -05:00
bunnei
66e023fba2 Merge pull request #2167 from lioncash/namespace
common: Move Quaternion, Rectangle, Vec2, Vec3, and Vec4 into the Common namespace
2019-02-27 11:19:53 -05:00
bunnei
b27e6ad912 Merge pull request #2171 from lioncash/pragma
gl_shader_disk_cache: Remove #pragma once from cpp file
2019-02-27 11:19:17 -05:00
Lioncash
e7eff72e83 gl_shader_disk_cache: Remove #pragma once from cpp file
This is only necessary in headers. Silences a warning with clang.
2019-02-27 11:02:49 -05:00
Lioncash
46b3209abb core/frontend/emu_window: Make ClipToTouchScreen a const member function
This member function doesn't modify instance state, so it can have the
const specifier applied to it.
2019-02-27 08:54:42 -05:00
Lioncash
0e1b5acc6a audio_core/audio_renderer: Name previously unknown parameters of AudioRendererParameter
Provides names for previously unknown entries (aside from the two u8
that appear to be padding bytes, and a single word that also appears
to be reserved or padding).

This will be useful in subsequent changes when unstubbing behavior related
to the audio renderer services.
2019-02-27 06:09:07 -05:00
Lioncash
b9238edd0d common/math_util: Move contents into the Common namespace
These types are within the common library, so they should be within the
Common namespace.
2019-02-27 03:38:39 -05:00
Lioncash
e56f32a071 externals: Update cubeb to 6f2420de8f155b10330cf973900ac7bdbfee589d
Keeps the audio library we use up to date.
2019-02-27 01:21:51 -05:00
Lioncash
1b855efd5e common/vector_math: Move Vec[x] types into the Common namespace
These types are within the common library, so they should be using the
Common namespace.
2019-02-26 22:38:36 -05:00
Lioncash
a1574aabd5 common/quaternion: Move Quaternion into the Common namespace
Quaternion is within the common library, so it should be using the
Common namespace.
2019-02-26 22:31:17 -05:00
bunnei
10d1d58390 Merge pull request #2164 from ReinUsesLisp/configure-blit
renderer_opengl: Update pixel format tracking
2019-02-26 12:12:10 -05:00
ReinUsesLisp
d91e35a50a renderer_opengl: Update pixel format tracking 2019-02-26 03:47:16 -03:00
Lioncash
d29f9e9709 kernel/handle_table: Make local variables as const where applicable
Makes immutable state explicit.
2019-02-25 11:12:38 -05:00
Lioncash
5167d1577d kernel/handle_table: Allow process capabilities to limit the handle table size
The kernel allows restricting the total size of the handle table through
the process capability descriptors. Until now, this functionality wasn't
hooked up. With this, the process handle tables become properly restricted.

In the case of metadata-less executables, the handle table will assume
the maximum size is requested, preserving the behavior that existed
before these changes.
2019-02-25 11:12:32 -05:00
Lioncash
4f8cd74061 kernel/handle-table: In-class initialize data members
Directly initializes members where applicable.
2019-02-25 10:14:05 -05:00
Lioncash
0220862ba5 kernel/handle_table: Resolve truncation warnings
Avoids implicit truncation warnings from u32 -> u16 (the truncation is
desirable behavior here).
2019-02-25 09:53:21 -05:00
37 changed files with 170 additions and 125 deletions

View File

@@ -46,16 +46,18 @@ struct AudioRendererParameter {
u32_le sample_rate;
u32_le sample_count;
u32_le mix_buffer_count;
u32_le unknown_c;
u32_le submix_count;
u32_le voice_count;
u32_le sink_count;
u32_le effect_count;
u32_le unknown_1c;
u8 unknown_20;
INSERT_PADDING_BYTES(3);
u32_le performance_frame_count;
u8 is_voice_drop_enabled;
u8 unknown_21;
u8 unknown_22;
u8 execution_mode;
u32_le splitter_count;
u32_le unknown_2c;
INSERT_PADDING_WORDS(1);
u32_le num_splitter_send_channels;
u32_le unknown_30;
u32_le revision;
};
static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");

View File

@@ -55,36 +55,36 @@ constexpr u8 Convert8To6(u8 value) {
/**
* Decode a color stored in RGBA8 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGBA8(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGBA8(const u8* bytes) {
return {bytes[3], bytes[2], bytes[1], bytes[0]};
}
/**
* Decode a color stored in RGB8 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGB8(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGB8(const u8* bytes) {
return {bytes[2], bytes[1], bytes[0], 255};
}
/**
* Decode a color stored in RG8 (aka HILO8) format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRG8(const u8* bytes) {
inline Common::Vec4<u8> DecodeRG8(const u8* bytes) {
return {bytes[1], bytes[0], 0, 255};
}
/**
* Decode a color stored in RGB565 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGB565(const u8* bytes) {
u16_le pixel;
std::memcpy(&pixel, bytes, sizeof(pixel));
return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F),
@@ -94,9 +94,9 @@ inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
/**
* Decode a color stored in RGB5A1 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
u16_le pixel;
std::memcpy(&pixel, bytes, sizeof(pixel));
return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F),
@@ -106,9 +106,9 @@ inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
/**
* Decode a color stored in RGBA4 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGBA4(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGBA4(const u8* bytes) {
u16_le pixel;
std::memcpy(&pixel, bytes, sizeof(pixel));
return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF),
@@ -138,9 +138,9 @@ inline u32 DecodeD24(const u8* bytes) {
/**
* Decode a depth value and a stencil value stored in D24S8 format
* @param bytes Pointer to encoded source values
* @return Resulting values stored as a Math::Vec2
* @return Resulting values stored as a Common::Vec2
*/
inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) {
inline Common::Vec2<u32> DecodeD24S8(const u8* bytes) {
return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]};
}
@@ -149,7 +149,7 @@ inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGBA8(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGBA8(const Common::Vec4<u8>& color, u8* bytes) {
bytes[3] = color.r();
bytes[2] = color.g();
bytes[1] = color.b();
@@ -161,7 +161,7 @@ inline void EncodeRGBA8(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGB8(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGB8(const Common::Vec4<u8>& color, u8* bytes) {
bytes[2] = color.r();
bytes[1] = color.g();
bytes[0] = color.b();
@@ -172,7 +172,7 @@ inline void EncodeRGB8(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRG8(const Common::Vec4<u8>& color, u8* bytes) {
bytes[1] = color.r();
bytes[0] = color.g();
}
@@ -181,7 +181,7 @@ inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGB565(const Common::Vec4<u8>& color, u8* bytes) {
const u16_le data =
(Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b());
@@ -193,7 +193,7 @@ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGB5A1(const Common::Vec4<u8>& color, u8* bytes) {
const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To5(color.g()) << 6) |
(Convert8To5(color.b()) << 1) | Convert8To1(color.a());
@@ -205,7 +205,7 @@ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGBA4(const Common::Vec4<u8>& color, u8* bytes) {
const u16 data = (Convert8To4(color.r()) << 12) | (Convert8To4(color.g()) << 8) |
(Convert8To4(color.b()) << 4) | Convert8To4(color.a());

View File

@@ -7,7 +7,7 @@
#include <cstdlib>
#include <type_traits>
namespace MathUtil {
namespace Common {
constexpr float PI = 3.14159265f;
@@ -41,4 +41,4 @@ struct Rectangle {
}
};
} // namespace MathUtil
} // namespace Common

View File

@@ -6,12 +6,12 @@
#include "common/vector_math.h"
namespace Math {
namespace Common {
template <typename T>
class Quaternion {
public:
Math::Vec3<T> xyz;
Vec3<T> xyz;
T w{};
Quaternion<decltype(-T{})> Inverse() const {
@@ -38,12 +38,12 @@ public:
};
template <typename T>
auto QuaternionRotate(const Quaternion<T>& q, const Math::Vec3<T>& v) {
auto QuaternionRotate(const Quaternion<T>& q, const Vec3<T>& v) {
return v + 2 * Cross(q.xyz, Cross(q.xyz, v) + v * q.w);
}
inline Quaternion<float> MakeQuaternion(const Math::Vec3<float>& axis, float angle) {
inline Quaternion<float> MakeQuaternion(const Vec3<float>& axis, float angle) {
return {axis * std::sin(angle / 2), std::cos(angle / 2)};
}
} // namespace Math
} // namespace Common

View File

@@ -33,7 +33,7 @@
#include <cmath>
#include <type_traits>
namespace Math {
namespace Common {
template <typename T>
class Vec2;
@@ -690,4 +690,4 @@ constexpr Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) {
return MakeVec(x, yzw[0], yzw[1], yzw[2]);
}
} // namespace Math
} // namespace Common

View File

@@ -67,7 +67,7 @@ static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigne
framebuffer_x >= layout.screen.left && framebuffer_x < layout.screen.right);
}
std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) {
std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const {
new_x = std::max(new_x, framebuffer_layout.screen.left);
new_x = std::min(new_x, framebuffer_layout.screen.right - 1);

View File

@@ -166,7 +166,7 @@ private:
/**
* Clip the provided coordinates to be inside the touchscreen area.
*/
std::tuple<unsigned, unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y);
std::tuple<unsigned, unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y) const;
};
} // namespace Core::Frontend

View File

@@ -12,12 +12,12 @@ namespace Layout {
// Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
template <class T>
static MathUtil::Rectangle<T> maxRectangle(MathUtil::Rectangle<T> window_area,
float screen_aspect_ratio) {
static Common::Rectangle<T> MaxRectangle(Common::Rectangle<T> window_area,
float screen_aspect_ratio) {
float scale = std::min(static_cast<float>(window_area.GetWidth()),
window_area.GetHeight() / screen_aspect_ratio);
return MathUtil::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
static_cast<T>(std::round(scale * screen_aspect_ratio))};
return Common::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
static_cast<T>(std::round(scale * screen_aspect_ratio))};
}
FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height) {
@@ -29,8 +29,8 @@ FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height) {
const float emulation_aspect_ratio{static_cast<float>(ScreenUndocked::Height) /
ScreenUndocked::Width};
MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
MathUtil::Rectangle<unsigned> screen = maxRectangle(screen_window_area, emulation_aspect_ratio);
Common::Rectangle<unsigned> screen_window_area{0, 0, width, height};
Common::Rectangle<unsigned> screen = MaxRectangle(screen_window_area, emulation_aspect_ratio);
float window_aspect_ratio = static_cast<float>(height) / width;

View File

@@ -16,7 +16,7 @@ struct FramebufferLayout {
unsigned width{ScreenUndocked::Width};
unsigned height{ScreenUndocked::Height};
MathUtil::Rectangle<unsigned> screen;
Common::Rectangle<unsigned> screen;
/**
* Returns the ration of pixel size of the screen, compared to the native size of the undocked

View File

@@ -124,7 +124,7 @@ using AnalogDevice = InputDevice<std::tuple<float, float>>;
* Orientation is determined by right-hand rule.
* Units: deg/sec
*/
using MotionDevice = InputDevice<std::tuple<Math::Vec3<float>, Math::Vec3<float>>>;
using MotionDevice = InputDevice<std::tuple<Common::Vec3<float>, Common::Vec3<float>>>;
/**
* A touch device is an input device that returns a tuple of two floats and a bool. The floats are

View File

@@ -14,6 +14,7 @@ constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED{ErrorModule::Kernel, 7};
constexpr ResultCode ERR_INVALID_CAPABILITY_DESCRIPTOR{ErrorModule::Kernel, 14};
constexpr ResultCode ERR_INVALID_SIZE{ErrorModule::Kernel, 101};
constexpr ResultCode ERR_INVALID_ADDRESS{ErrorModule::Kernel, 102};
constexpr ResultCode ERR_OUT_OF_MEMORY{ErrorModule::Kernel, 104};
constexpr ResultCode ERR_HANDLE_TABLE_FULL{ErrorModule::Kernel, 105};
constexpr ResultCode ERR_INVALID_ADDRESS_STATE{ErrorModule::Kernel, 106};
constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS{ErrorModule::Kernel, 108};

View File

@@ -14,32 +14,47 @@
namespace Kernel {
namespace {
constexpr u16 GetSlot(Handle handle) {
return handle >> 15;
return static_cast<u16>(handle >> 15);
}
constexpr u16 GetGeneration(Handle handle) {
return handle & 0x7FFF;
return static_cast<u16>(handle & 0x7FFF);
}
} // Anonymous namespace
HandleTable::HandleTable() {
next_generation = 1;
Clear();
}
HandleTable::~HandleTable() = default;
ResultCode HandleTable::SetSize(s32 handle_table_size) {
if (static_cast<u32>(handle_table_size) > MAX_COUNT) {
return ERR_OUT_OF_MEMORY;
}
// Values less than or equal to zero indicate to use the maximum allowable
// size for the handle table in the actual kernel, so we ignore the given
// value in that case, since we assume this by default unless this function
// is called.
if (handle_table_size > 0) {
table_size = static_cast<u16>(handle_table_size);
}
return RESULT_SUCCESS;
}
ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
DEBUG_ASSERT(obj != nullptr);
u16 slot = next_free_slot;
if (slot >= generations.size()) {
const u16 slot = next_free_slot;
if (slot >= table_size) {
LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
return ERR_HANDLE_TABLE_FULL;
}
next_free_slot = generations[slot];
u16 generation = next_generation++;
const u16 generation = next_generation++;
// Overflow count so it fits in the 15 bits dedicated to the generation in the handle.
// Horizon OS uses zero to represent an invalid handle, so skip to 1.
@@ -64,10 +79,11 @@ ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
}
ResultCode HandleTable::Close(Handle handle) {
if (!IsValid(handle))
if (!IsValid(handle)) {
return ERR_INVALID_HANDLE;
}
u16 slot = GetSlot(handle);
const u16 slot = GetSlot(handle);
objects[slot] = nullptr;
@@ -77,10 +93,10 @@ ResultCode HandleTable::Close(Handle handle) {
}
bool HandleTable::IsValid(Handle handle) const {
std::size_t slot = GetSlot(handle);
u16 generation = GetGeneration(handle);
const std::size_t slot = GetSlot(handle);
const u16 generation = GetGeneration(handle);
return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
return slot < table_size && objects[slot] != nullptr && generations[slot] == generation;
}
SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
@@ -97,7 +113,7 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
}
void HandleTable::Clear() {
for (u16 i = 0; i < MAX_COUNT; ++i) {
for (u16 i = 0; i < table_size; ++i) {
generations[i] = i + 1;
objects[i] = nullptr;
}

View File

@@ -49,6 +49,20 @@ public:
HandleTable();
~HandleTable();
/**
* Sets the number of handles that may be in use at one time
* for this handle table.
*
* @param handle_table_size The desired size to limit the handle table to.
*
* @returns an error code indicating if initialization was successful.
* If initialization was not successful, then ERR_OUT_OF_MEMORY
* will be returned.
*
* @pre handle_table_size must be within the range [0, 1024]
*/
ResultCode SetSize(s32 handle_table_size);
/**
* Allocates a handle for the given object.
* @return The created Handle or one of the following errors:
@@ -103,14 +117,21 @@ private:
*/
std::array<u16, MAX_COUNT> generations;
/**
* The limited size of the handle table. This can be specified by process
* capabilities in order to restrict the overall number of handles that
* can be created in a process instance
*/
u16 table_size = static_cast<u16>(MAX_COUNT);
/**
* Global counter of the number of created handles. Stored in `generations` when a handle is
* created, and wraps around to 1 when it hits 0x8000.
*/
u16 next_generation;
u16 next_generation = 1;
/// Head of the free slots linked list.
u16 next_free_slot;
u16 next_free_slot = 0;
};
} // namespace Kernel

View File

@@ -99,7 +99,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
vm_manager.Reset(metadata.GetAddressSpaceType());
const auto& caps = metadata.GetKernelCapabilities();
return capabilities.InitializeForUserProcess(caps.data(), caps.size(), vm_manager);
const auto capability_init_result =
capabilities.InitializeForUserProcess(caps.data(), caps.size(), vm_manager);
if (capability_init_result.IsError()) {
return capability_init_result;
}
return handle_table.SetSize(capabilities.GetHandleTableSize());
}
void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {

View File

@@ -96,7 +96,7 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() {
interrupt_capabilities.set();
// Allow using the maximum possible amount of handles
handle_table_size = static_cast<u32>(HandleTable::MAX_COUNT);
handle_table_size = static_cast<s32>(HandleTable::MAX_COUNT);
// Allow all debugging capabilities.
is_debuggable = true;
@@ -337,7 +337,7 @@ ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) {
return ERR_RESERVED_VALUE;
}
handle_table_size = (flags >> 16) & 0x3FF;
handle_table_size = static_cast<s32>((flags >> 16) & 0x3FF);
return RESULT_SUCCESS;
}

View File

@@ -156,7 +156,7 @@ public:
}
/// Gets the number of total allowable handles for the process' handle table.
u32 GetHandleTableSize() const {
s32 GetHandleTableSize() const {
return handle_table_size;
}
@@ -252,7 +252,7 @@ private:
u64 core_mask = 0;
u64 priority_mask = 0;
u32 handle_table_size = 0;
s32 handle_table_size = 0;
u32 kernel_version = 0;
ProgramType program_type = ProgramType::SysModule;

View File

@@ -262,20 +262,20 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
u64 buffer_sz = Common::AlignUp(4 * params.mix_buffer_count, 0x40);
buffer_sz += params.unknown_c * 1024;
buffer_sz += 0x940 * (params.unknown_c + 1);
buffer_sz += params.submix_count * 1024;
buffer_sz += 0x940 * (params.submix_count + 1);
buffer_sz += 0x3F0 * params.voice_count;
buffer_sz += Common::AlignUp(8 * (params.unknown_c + 1), 0x10);
buffer_sz += Common::AlignUp(8 * (params.submix_count + 1), 0x10);
buffer_sz += Common::AlignUp(8 * params.voice_count, 0x10);
buffer_sz +=
Common::AlignUp((0x3C0 * (params.sink_count + params.unknown_c) + 4 * params.sample_count) *
(params.mix_buffer_count + 6),
0x40);
buffer_sz += Common::AlignUp(
(0x3C0 * (params.sink_count + params.submix_count) + 4 * params.sample_count) *
(params.mix_buffer_count + 6),
0x40);
if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) {
u32 count = params.unknown_c + 1;
const u32 count = params.submix_count + 1;
u64 node_count = Common::AlignUp(count, 0x40);
u64 node_state_buffer_sz =
const u64 node_state_buffer_sz =
4 * (node_count * node_count) + 0xC * node_count + 2 * (node_count / 8);
u64 edge_matrix_buffer_sz = 0;
node_count = Common::AlignUp(count * count, 0x40);
@@ -289,19 +289,19 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
buffer_sz += 0x20 * (params.effect_count + 4 * params.voice_count) + 0x50;
if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) {
buffer_sz += 0xE0 * params.unknown_2c;
buffer_sz += 0xE0 * params.num_splitter_send_channels;
buffer_sz += 0x20 * params.splitter_count;
buffer_sz += Common::AlignUp(4 * params.unknown_2c, 0x10);
buffer_sz += Common::AlignUp(4 * params.num_splitter_send_channels, 0x10);
}
buffer_sz = Common::AlignUp(buffer_sz, 0x40) + 0x170 * params.sink_count;
u64 output_sz = buffer_sz + 0x280 * params.sink_count + 0x4B0 * params.effect_count +
((params.voice_count * 256) | 0x40);
if (params.unknown_1c >= 1) {
if (params.performance_frame_count >= 1) {
output_sz = Common::AlignUp(((16 * params.sink_count + 16 * params.effect_count +
16 * params.voice_count + 16) +
0x658) *
(params.unknown_1c + 1) +
(params.performance_frame_count + 1) +
0xc0,
0x40) +
output_sz;

View File

@@ -15,7 +15,7 @@ namespace Kernel {
class SharedMemory;
}
namespace SM {
namespace Service::SM {
class ServiceManager;
}

View File

@@ -23,7 +23,7 @@ u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector
void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height,
u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform,
const MathUtil::Rectangle<int>& crop_rect) {
const Common::Rectangle<int>& crop_rect) {
VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
LOG_TRACE(Service,
"Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",

View File

@@ -25,7 +25,7 @@ public:
/// Performs a screen flip, drawing the buffer pointed to by the handle.
void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
NVFlinger::BufferQueue::BufferTransformFlags transform,
const MathUtil::Rectangle<int>& crop_rect);
const Common::Rectangle<int>& crop_rect);
private:
std::shared_ptr<nvmap> nvmap_dev;

View File

@@ -63,7 +63,7 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const {
}
void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
const MathUtil::Rectangle<int>& crop_rect) {
const Common::Rectangle<int>& crop_rect) {
auto itr = std::find_if(queue.begin(), queue.end(),
[&](const Buffer& buffer) { return buffer.slot == slot; });
ASSERT(itr != queue.end());

View File

@@ -67,14 +67,14 @@ public:
Status status = Status::Free;
IGBPBuffer igbp_buffer;
BufferTransformFlags transform;
MathUtil::Rectangle<int> crop_rect;
Common::Rectangle<int> crop_rect;
};
void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer);
std::optional<u32> DequeueBuffer(u32 width, u32 height);
const IGBPBuffer& RequestBuffer(u32 slot) const;
void QueueBuffer(u32 slot, BufferTransformFlags transform,
const MathUtil::Rectangle<int>& crop_rect);
const Common::Rectangle<int>& crop_rect);
std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
void ReleaseBuffer(u32 slot);
u32 Query(QueryType type);

View File

@@ -420,7 +420,7 @@ public:
u32_le fence_is_valid;
std::array<Fence, 2> fences;
MathUtil::Rectangle<int> GetCropRect() const {
Common::Rectangle<int> GetCropRect() const {
return {crop_left, crop_top, crop_right, crop_bottom};
}
};

View File

@@ -32,12 +32,12 @@ public:
}
void BeginTilt(int x, int y) {
mouse_origin = Math::MakeVec(x, y);
mouse_origin = Common::MakeVec(x, y);
is_tilting = true;
}
void Tilt(int x, int y) {
auto mouse_move = Math::MakeVec(x, y) - mouse_origin;
auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
if (is_tilting) {
std::lock_guard<std::mutex> guard(tilt_mutex);
if (mouse_move.x == 0 && mouse_move.y == 0) {
@@ -45,7 +45,7 @@ public:
} else {
tilt_direction = mouse_move.Cast<float>();
tilt_angle =
std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, MathUtil::PI * 0.5f);
std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f);
}
}
}
@@ -56,7 +56,7 @@ public:
is_tilting = false;
}
std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() {
std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() {
std::lock_guard<std::mutex> guard(status_mutex);
return status;
}
@@ -66,17 +66,17 @@ private:
const std::chrono::steady_clock::duration update_duration;
const float sensitivity;
Math::Vec2<int> mouse_origin;
Common::Vec2<int> mouse_origin;
std::mutex tilt_mutex;
Math::Vec2<float> tilt_direction;
Common::Vec2<float> tilt_direction;
float tilt_angle = 0;
bool is_tilting = false;
Common::Event shutdown_event;
std::tuple<Math::Vec3<float>, Math::Vec3<float>> status;
std::tuple<Common::Vec3<float>, Common::Vec3<float>> status;
std::mutex status_mutex;
// Note: always keep the thread declaration at the end so that other objects are initialized
@@ -85,8 +85,8 @@ private:
void MotionEmuThread() {
auto update_time = std::chrono::steady_clock::now();
Math::Quaternion<float> q = MakeQuaternion(Math::Vec3<float>(), 0);
Math::Quaternion<float> old_q;
Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0);
Common::Quaternion<float> old_q;
while (!shutdown_event.WaitUntil(update_time)) {
update_time += update_duration;
@@ -96,18 +96,18 @@ private:
std::lock_guard<std::mutex> guard(tilt_mutex);
// Find the quaternion describing current 3DS tilting
q = MakeQuaternion(Math::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x),
tilt_angle);
q = Common::MakeQuaternion(
Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle);
}
auto inv_q = q.Inverse();
// Set the gravity vector in world space
auto gravity = Math::MakeVec(0.0f, -1.0f, 0.0f);
auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f);
// Find the angular rate vector in world space
auto angular_rate = ((q - old_q) * inv_q).xyz * 2;
angular_rate *= 1000 / update_millisecond / MathUtil::PI * 180;
angular_rate *= 1000 / update_millisecond / Common::PI * 180;
// Transform the two vectors from world space to 3DS space
gravity = QuaternionRotate(inv_q, gravity);
@@ -131,7 +131,7 @@ public:
device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
}
std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const override {
std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() const override {
return device->GetStatus();
}

View File

@@ -44,10 +44,10 @@ void Fermi2D::HandleSurfaceCopy() {
const u32 src_blit_y2{
static_cast<u32>((regs.blit_src_y + (regs.blit_dst_height * regs.blit_dv_dy)) >> 32)};
const MathUtil::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2};
const MathUtil::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y,
regs.blit_dst_x + regs.blit_dst_width,
regs.blit_dst_y + regs.blit_dst_height};
const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2};
const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y,
regs.blit_dst_x + regs.blit_dst_width,
regs.blit_dst_y + regs.blit_dst_height};
if (!rasterizer.AccelerateSurfaceCopy(regs.src, regs.dst, src_rect, dst_rect)) {
UNIMPLEMENTED();

View File

@@ -503,7 +503,7 @@ public:
f32 translate_z;
INSERT_PADDING_WORDS(2);
MathUtil::Rectangle<s32> GetRect() const {
Common::Rectangle<s32> GetRect() const {
return {
GetX(), // left
GetY() + GetHeight(), // top

View File

@@ -100,7 +100,7 @@ struct FramebufferConfig {
using TransformFlags = Service::NVFlinger::BufferQueue::BufferTransformFlags;
TransformFlags transform_flags;
MathUtil::Rectangle<int> crop_rect;
Common::Rectangle<int> crop_rect;
};
namespace Engines {

View File

@@ -47,8 +47,8 @@ public:
/// Attempt to use a faster method to perform a surface copy
virtual bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
const Tegra::Engines::Fermi2D::Regs::Surface& dst,
const MathUtil::Rectangle<u32>& src_rect,
const MathUtil::Rectangle<u32>& dst_rect) {
const Common::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& dst_rect) {
return false;
}

View File

@@ -779,8 +779,8 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
const Tegra::Engines::Fermi2D::Regs::Surface& dst,
const MathUtil::Rectangle<u32>& src_rect,
const MathUtil::Rectangle<u32>& dst_rect) {
const Common::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& dst_rect) {
MICROPROFILE_SCOPE(OpenGL_Blits);
res_cache.FermiCopySurface(src, dst, src_rect, dst_rect);
return true;
@@ -1034,7 +1034,7 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
for (std::size_t i = 0; i < viewport_count; i++) {
auto& viewport = current_state.viewports[i];
const auto& src = regs.viewports[i];
const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
viewport.x = viewport_rect.left;
viewport.y = viewport_rect.bottom;
viewport.width = viewport_rect.GetWidth();

View File

@@ -62,8 +62,8 @@ public:
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
const Tegra::Engines::Fermi2D::Regs::Surface& dst,
const MathUtil::Rectangle<u32>& src_rect,
const MathUtil::Rectangle<u32>& dst_rect) override;
const Common::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& dst_rect) override;
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
u32 pixel_stride) override;
bool AccelerateDrawBatch(bool is_indexed) override;

View File

@@ -399,7 +399,7 @@ static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType
return format;
}
MathUtil::Rectangle<u32> SurfaceParams::GetRect(u32 mip_level) const {
Common::Rectangle<u32> SurfaceParams::GetRect(u32 mip_level) const {
u32 actual_height{std::max(1U, unaligned_height >> mip_level)};
if (IsPixelFormatASTC(pixel_format)) {
// ASTC formats must stop at the ATSC block size boundary
@@ -1062,8 +1062,8 @@ void RasterizerCacheOpenGL::FastLayeredCopySurface(const Surface& src_surface,
}
static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
const MathUtil::Rectangle<u32>& src_rect,
const MathUtil::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
const Common::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
GLuint draw_fb_handle, GLenum src_attachment = 0, GLenum dst_attachment = 0,
std::size_t cubemap_face = 0) {
@@ -1193,7 +1193,7 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
void RasterizerCacheOpenGL::FermiCopySurface(
const Tegra::Engines::Fermi2D::Regs::Surface& src_config,
const Tegra::Engines::Fermi2D::Regs::Surface& dst_config,
const MathUtil::Rectangle<u32>& src_rect, const MathUtil::Rectangle<u32>& dst_rect) {
const Common::Rectangle<u32>& src_rect, const Common::Rectangle<u32>& dst_rect) {
const auto& src_params = SurfaceParams::CreateForFermiCopySurface(src_config);
const auto& dst_params = SurfaceParams::CreateForFermiCopySurface(dst_config);

View File

@@ -28,7 +28,7 @@ namespace OpenGL {
class CachedSurface;
using Surface = std::shared_ptr<CachedSurface>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>;
using SurfaceTarget = VideoCore::Surface::SurfaceTarget;
using SurfaceType = VideoCore::Surface::SurfaceType;
@@ -71,7 +71,7 @@ struct SurfaceParams {
}
/// Returns the rectangle corresponding to this surface
MathUtil::Rectangle<u32> GetRect(u32 mip_level = 0) const;
Common::Rectangle<u32> GetRect(u32 mip_level = 0) const;
/// Returns the total size of this surface in bytes, adjusted for compression
std::size_t SizeInBytesRaw(bool ignore_tiled = false) const {
@@ -430,8 +430,8 @@ public:
/// Copies the contents of one surface to another
void FermiCopySurface(const Tegra::Engines::Fermi2D::Regs::Surface& src_config,
const Tegra::Engines::Fermi2D::Regs::Surface& dst_config,
const MathUtil::Rectangle<u32>& src_rect,
const MathUtil::Rectangle<u32>& dst_rect);
const Common::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& dst_rect);
private:
void LoadSurface(const Surface& surface);

View File

@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <cstring>
#include <fmt/format.h>
#include <lz4.h>

View File

@@ -257,6 +257,7 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
const Tegra::FramebufferConfig& framebuffer) {
texture.width = framebuffer.width;
texture.height = framebuffer.height;
texture.pixel_format = framebuffer.pixel_format;
GLint internal_format;
switch (framebuffer.pixel_format) {

View File

@@ -39,7 +39,7 @@ struct TextureInfo {
/// Structure used for storing information about the display target for the Switch screen
struct ScreenInfo {
GLuint display_texture;
const MathUtil::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
TextureInfo texture;
};
@@ -102,7 +102,7 @@ private:
/// Used for transforming the framebuffer orientation
Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags;
MathUtil::Rectangle<int> framebuffer_crop_rect;
Common::Rectangle<int> framebuffer_crop_rect;
};
} // namespace OpenGL

View File

@@ -398,7 +398,7 @@ void GraphicsSurfaceWidget::OnUpdate() {
for (unsigned int y = 0; y < surface_height; ++y) {
for (unsigned int x = 0; x < surface_width; ++x) {
Math::Vec4<u8> color;
Common::Vec4<u8> color;
color[0] = texture_data[x + y * surface_width + 0];
color[1] = texture_data[x + y * surface_width + 1];
color[2] = texture_data[x + y * surface_width + 2];