Merge pull request #4666 from FearlessTobi/port-2167

Port yuzu-emu/yuzu#2167: "common: Move Quaternion, Rectangle, Vec2, Vec3, and Vec4 into the Common namespace"
This commit is contained in:
bunnei 2019-03-07 23:52:42 -05:00 committed by GitHub
commit 9560060f04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 390 additions and 380 deletions

View file

@ -29,7 +29,7 @@ QImage LoadTexture(const u8* src, const Pica::Texture::TextureInfo& info) {
QImage decoded_image(info.width, info.height, QImage::Format_ARGB32);
for (u32 y = 0; y < info.height; ++y) {
for (u32 x = 0; x < info.width; ++x) {
Math::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true);
decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
}
}

View file

@ -585,7 +585,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 = Pica::Texture::LookupTexture(buffer, x, y, info, true);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(buffer, x, y, info, true);
decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
}
}
@ -605,7 +605,7 @@ void GraphicsSurfaceWidget::OnUpdate() {
const u32 coarse_y = y & ~7;
u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
const u8* pixel = buffer + offset;
Math::Vec4<u8> color = {0, 0, 0, 0};
Common::Vec4<u8> color = {0, 0, 0, 0};
switch (surface_format) {
case Format::D16: {
@ -622,14 +622,14 @@ void GraphicsSurfaceWidget::OnUpdate() {
break;
}
case Format::D24X8: {
Math::Vec2<u32> data = Color::DecodeD24S8(pixel);
Common::Vec2<u32> data = Color::DecodeD24S8(pixel);
color.r() = data.x & 0xFF;
color.g() = (data.x >> 8) & 0xFF;
color.b() = (data.x >> 16) & 0xFF;
break;
}
case Format::X24S8: {
Math::Vec2<u32> data = Color::DecodeD24S8(pixel);
Common::Vec2<u32> data = Color::DecodeD24S8(pixel);
color.r() = color.g() = color.b() = data.y;
break;
}

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,13 +6,13 @@
#include "common/vector_math.h"
namespace Math {
namespace Common {
template <typename T>
class Quaternion {
public:
Math::Vec3<T> xyz;
T w;
Vec3<T> xyz;
T w{};
Quaternion<decltype(-T{})> Inverse() const {
return {-xyz, w};
@ -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;
@ -702,4 +702,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

@ -22,12 +22,12 @@ u16 FramebufferLayout::GetScalingRatio() const {
// 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, bool swapped) {
@ -36,10 +36,10 @@ FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool swapp
FramebufferLayout res{width, height, true, true, {}, {}};
// Default layout gives equal screen sizes to the top and bottom screen
MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height / 2};
MathUtil::Rectangle<unsigned> top_screen =
Common::Rectangle<unsigned> screen_window_area{0, 0, width, height / 2};
Common::Rectangle<unsigned> top_screen =
maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
MathUtil::Rectangle<unsigned> bot_screen =
Common::Rectangle<unsigned> bot_screen =
maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO);
float window_aspect_ratio = static_cast<float>(height) / width;
@ -77,10 +77,10 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool swappe
// so just calculate them both even if the other isn't showing.
FramebufferLayout res{width, height, !swapped, swapped, {}, {}};
MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
MathUtil::Rectangle<unsigned> top_screen =
Common::Rectangle<unsigned> screen_window_area{0, 0, width, height};
Common::Rectangle<unsigned> top_screen =
maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
MathUtil::Rectangle<unsigned> bot_screen =
Common::Rectangle<unsigned> bot_screen =
maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO);
float window_aspect_ratio = static_cast<float>(height) / width;
@ -116,13 +116,12 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped
float large_screen_aspect_ratio = swapped ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO;
float small_screen_aspect_ratio = swapped ? TOP_SCREEN_ASPECT_RATIO : BOT_SCREEN_ASPECT_RATIO;
MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
MathUtil::Rectangle<unsigned> total_rect =
Common::Rectangle<unsigned> screen_window_area{0, 0, width, height};
Common::Rectangle<unsigned> total_rect =
maxRectangle(screen_window_area, emulation_aspect_ratio);
MathUtil::Rectangle<unsigned> large_screen =
maxRectangle(total_rect, large_screen_aspect_ratio);
MathUtil::Rectangle<unsigned> fourth_size_rect = total_rect.Scale(.25f);
MathUtil::Rectangle<unsigned> small_screen =
Common::Rectangle<unsigned> large_screen = maxRectangle(total_rect, large_screen_aspect_ratio);
Common::Rectangle<unsigned> fourth_size_rect = total_rect.Scale(.25f);
Common::Rectangle<unsigned> small_screen =
maxRectangle(fourth_size_rect, small_screen_aspect_ratio);
if (window_aspect_ratio < emulation_aspect_ratio) {
@ -149,13 +148,13 @@ FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool swapped)
const float emulation_aspect_ratio = static_cast<float>(Core::kScreenTopHeight) /
(Core::kScreenTopWidth + Core::kScreenBottomWidth);
float window_aspect_ratio = static_cast<float>(height) / width;
MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
Common::Rectangle<unsigned> screen_window_area{0, 0, width, height};
// Find largest Rectangle that can fit in the window size with the given aspect ratio
MathUtil::Rectangle<unsigned> screen_rect =
Common::Rectangle<unsigned> screen_rect =
maxRectangle(screen_window_area, emulation_aspect_ratio);
// Find sizes of top and bottom screen
MathUtil::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO);
MathUtil::Rectangle<unsigned> bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO);
Common::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO);
Common::Rectangle<unsigned> bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO);
if (window_aspect_ratio < emulation_aspect_ratio) {
// Apply borders to the left and right sides of the window.
@ -180,10 +179,10 @@ FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
FramebufferLayout res{width, height, true, true, {}, {}};
MathUtil::Rectangle<unsigned> top_screen{
Common::Rectangle<unsigned> top_screen{
Settings::values.custom_top_left, Settings::values.custom_top_top,
Settings::values.custom_top_right, Settings::values.custom_top_bottom};
MathUtil::Rectangle<unsigned> bot_screen{
Common::Rectangle<unsigned> bot_screen{
Settings::values.custom_bottom_left, Settings::values.custom_bottom_top,
Settings::values.custom_bottom_right, Settings::values.custom_bottom_bottom};

View file

@ -14,8 +14,8 @@ struct FramebufferLayout {
unsigned height;
bool top_screen_enabled;
bool bottom_screen_enabled;
MathUtil::Rectangle<unsigned> top_screen;
MathUtil::Rectangle<unsigned> bottom_screen;
Common::Rectangle<unsigned> top_screen;
Common::Rectangle<unsigned> bottom_screen;
/**
* Returns the ration of pixel size of the top screen, compared to the native size of the 3DS

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

@ -179,7 +179,7 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) {
mem->accelerometer.index = next_accelerometer_index;
next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size();
Math::Vec3<float> accel;
Common::Vec3<float> accel;
std::tie(accel, std::ignore) = motion_device->GetStatus();
accel *= accelerometer_coef;
// TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback
@ -226,7 +226,7 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) {
GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index];
Math::Vec3<float> gyro;
Common::Vec3<float> gyro;
std::tie(std::ignore, gyro) = motion_device->GetStatus();
double stretch = system.perf_stats.GetLastFrameTimeScale();
gyro *= gyroscope_coef * static_cast<float>(stretch);

View file

@ -48,7 +48,7 @@ inline void Read(T& var, const u32 raw_addr) {
var = g_regs[addr / 4];
}
static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
static Common::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
switch (input_format) {
case Regs::PixelFormat::RGBA8:
return Color::DecodeRGBA8(src_pixel);
@ -196,7 +196,7 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
for (u32 y = 0; y < output_height; ++y) {
for (u32 x = 0; x < output_width; ++x) {
Math::Vec4<u8> src_color;
Common::Vec4<u8> src_color;
// Calculate the [x,y] position of the input image
// based on the current output position and the scale
@ -259,15 +259,15 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
const u8* src_pixel = src_pointer + src_offset;
src_color = DecodePixel(config.input_format, src_pixel);
if (config.scaling == config.ScaleX) {
Math::Vec4<u8> pixel =
Common::Vec4<u8> pixel =
DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel);
src_color = ((src_color + pixel) / 2).Cast<u8>();
} else if (config.scaling == config.ScaleXY) {
Math::Vec4<u8> pixel1 =
Common::Vec4<u8> pixel1 =
DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel);
Math::Vec4<u8> pixel2 =
Common::Vec4<u8> pixel2 =
DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel);
Math::Vec4<u8> pixel3 =
Common::Vec4<u8> pixel3 =
DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel);
src_color = (((src_color + pixel1) + (pixel2 + pixel3)) / 4).Cast<u8>();
}

View file

@ -110,7 +110,7 @@ static void SendData(const u32* input, ConversionBuffer& buf, int amount_of_data
u8* unit_end = output + buf.transfer_unit;
while (output < unit_end) {
u32 color = *input++;
Math::Vec4<u8> col_vec{(u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), alpha};
Common::Vec4<u8> col_vec{(u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), alpha};
switch (output_format) {
case OutputFormat::RGBA8:

View file

@ -33,12 +33,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) {
@ -46,7 +46,7 @@ public:
} else {
tilt_direction = mouse_move.Cast<float>();
tilt_angle = std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f,
MathUtil::PI * this->tilt_clamp / 180.0f);
Common::PI * this->tilt_clamp / 180.0f);
}
}
}
@ -57,7 +57,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;
}
@ -67,10 +67,10 @@ 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;
float tilt_clamp = 90;
@ -78,7 +78,7 @@ private:
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
@ -87,8 +87,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;
@ -98,18 +98,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);
@ -133,7 +133,7 @@ public:
device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity, tilt_clamp);
}
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

@ -162,8 +162,8 @@ void Client::OnPadData(Response::PadData data) {
// Due to differences between the 3ds and cemuhookudp motion directions, we need to invert
// accel.x and accel.z and also invert pitch and yaw. See
// https://github.com/citra-emu/citra/pull/4049 for more details on gyro/accel
Math::Vec3f accel = Math::MakeVec<float>(-data.accel.x, data.accel.y, -data.accel.z);
Math::Vec3f gyro = Math::MakeVec<float>(-data.gyro.pitch, -data.gyro.yaw, data.gyro.roll);
Common::Vec3f accel = Common::MakeVec<float>(-data.accel.x, data.accel.y, -data.accel.z);
Common::Vec3f gyro = Common::MakeVec<float>(-data.gyro.pitch, -data.gyro.yaw, data.gyro.roll);
{
std::lock_guard<std::mutex> guard(status->update_mutex);

View file

@ -31,7 +31,7 @@ struct Version;
struct DeviceStatus {
std::mutex update_mutex;
std::tuple<Math::Vec3<float>, Math::Vec3<float>> motion_status;
std::tuple<Common::Vec3<float>, Common::Vec3<float>> motion_status;
std::tuple<float, float, bool> touch_status;
// calibration data for scaling the device's touch area to 3ds

View file

@ -26,7 +26,7 @@ private:
class UDPMotionDevice final : public Input::MotionDevice {
public:
explicit UDPMotionDevice(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {}
std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const {
std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() const {
std::lock_guard<std::mutex> guard(status->update_mutex);
return status->motion_status;
}

View file

@ -63,7 +63,7 @@ static void WriteUniformBoolReg(Shader::ShaderSetup& setup, u32 value) {
}
static void WriteUniformIntReg(Shader::ShaderSetup& setup, unsigned index,
const Math::Vec4<u8>& values) {
const Common::Vec4<u8>& values) {
ASSERT(index < setup.uniforms.i.size());
setup.uniforms.i[index] = values;
LOG_TRACE(HW_GPU, "Set {} integer uniform {} to {:02x} {:02x} {:02x} {:02x}",
@ -186,7 +186,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
break;
}
Math::Vec4<float24> attribute;
Common::Vec4<float24> attribute;
// NOTE: The destination component order indeed is "backwards"
attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
@ -447,7 +447,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
unsigned index = (id - PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[0], 0x281));
auto values = regs.gs.int_uniforms[index];
WriteUniformIntReg(g_state.gs, index,
Math::Vec4<u8>(values.x, values.y, values.z, values.w));
Common::Vec4<u8>(values.x, values.y, values.z, values.w));
break;
}
@ -515,7 +515,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
auto values = regs.vs.int_uniforms[index];
WriteUniformIntReg(g_state.vs, index,
Math::Vec4<u8>(values.x, values.y, values.z, values.w));
Common::Vec4<u8>(values.x, values.y, values.z, values.w));
break;
}

View file

@ -76,8 +76,8 @@ private:
const Regs& regs;
Shader::GSUnitState& unit;
Shader::AttributeBuffer attribute_buffer;
Math::Vec4<float24>* buffer_cur;
Math::Vec4<float24>* buffer_end;
Common::Vec4<float24>* buffer_cur;
Common::Vec4<float24>* buffer_end;
unsigned int vs_output_num;
};
@ -106,7 +106,7 @@ public:
// The number of vertex input is put to the uniform register
float24 vertex_num = float24::FromFloat32(static_cast<float>(val));
setup.uniforms.f[0] = Math::MakeVec(vertex_num, vertex_num, vertex_num, vertex_num);
setup.uniforms.f[0] = Common::MakeVec(vertex_num, vertex_num, vertex_num, vertex_num);
// The second uniform register and so on are used for receiving input vertices
buffer_cur = setup.uniforms.f + 1;
@ -142,7 +142,7 @@ private:
Shader::ShaderSetup& setup;
unsigned int main_vertex_num;
unsigned int total_vertex_num;
Math::Vec4<float24>* buffer_cur;
Common::Vec4<float24>* buffer_cur;
unsigned int vs_output_num;
};
@ -186,9 +186,9 @@ public:
private:
const Regs& regs;
Shader::ShaderSetup& setup;
Math::Vec4<float24>* buffer_begin;
Math::Vec4<float24>* buffer_cur;
Math::Vec4<float24>* buffer_end;
Common::Vec4<float24>* buffer_begin;
Common::Vec4<float24>* buffer_cur;
Common::Vec4<float24>* buffer_end;
unsigned int vs_output_num;
};

View file

@ -56,7 +56,7 @@ struct State {
BitField<16, 8, u32> b;
BitField<24, 8, u32> a;
Math::Vec4<u8> ToVector() const {
Common::Vec4<u8> ToVector() const {
return {static_cast<u8>(r), static_cast<u8>(g), static_cast<u8>(b),
static_cast<u8>(a)};
}
@ -69,8 +69,8 @@ struct State {
BitField<16, 8, s32> b;
BitField<24, 8, s32> a;
Math::Vec4<s32> ToVector() const {
return Math::Vec4<s32>{r, g, b, a} * 2;
Common::Vec4<s32> ToVector() const {
return Common::Vec4<s32>{r, g, b, a} * 2;
}
};

View file

@ -90,10 +90,10 @@ struct LightingRegs {
BitField<10, 10, u32> g;
BitField<20, 10, u32> r;
Math::Vec3f ToVec3f() const {
Common::Vec3f ToVec3f() const {
// These fields are 10 bits wide, however 255 corresponds to 1.0f for each color
// component
return Math::MakeVec((f32)r / 255.f, (f32)g / 255.f, (f32)b / 255.f);
return Common::MakeVec((f32)r / 255.f, (f32)g / 255.f, (f32)b / 255.f);
}
};

View file

@ -36,7 +36,7 @@ struct RasterizerRegs {
BitField<0, 1, u32> clip_enable;
BitField<0, 24, u32> clip_coef[4]; // float24
Math::Vec4<float24> GetClipCoef() const {
Common::Vec4<float24> GetClipCoef() const {
return {float24::FromRaw(clip_coef[0]), float24::FromRaw(clip_coef[1]),
float24::FromRaw(clip_coef[2]), float24::FromRaw(clip_coef[3])};
}

View file

@ -224,11 +224,11 @@ void RasterizerOpenGL::SyncEntireState() {
* Fortunately however, the 3DS hardware happens to also use this exact same logic to work around
* these issues, making this basic implementation actually more accurate to the hardware.
*/
static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) {
Math::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()};
Math::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()};
static bool AreQuaternionsOpposite(Common::Vec4<Pica::float24> qa, Common::Vec4<Pica::float24> qb) {
Common::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()};
Common::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()};
return (Math::Dot(a, b) < 0.f);
return (Common::Dot(a, b) < 0.f);
}
void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0,
@ -522,7 +522,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
(write_depth_fb || regs.framebuffer.output_merger.depth_test_enable != 0 ||
(has_stencil && state.stencil.test_enabled));
MathUtil::Rectangle<s32> viewport_rect_unscaled{
Common::Rectangle<s32> viewport_rect_unscaled{
// These registers hold half-width and half-height, so must be multiplied by 2
regs.rasterizer.viewport_corner.x, // left
regs.rasterizer.viewport_corner.y + // top
@ -536,7 +536,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
Surface color_surface;
Surface depth_surface;
MathUtil::Rectangle<u32> surfaces_rect;
Common::Rectangle<u32> surfaces_rect;
std::tie(color_surface, depth_surface, surfaces_rect) =
res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect_unscaled);
@ -544,7 +544,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
? color_surface->res_scale
: (depth_surface == nullptr ? 1u : depth_surface->res_scale);
MathUtil::Rectangle<u32> draw_rect{
Common::Rectangle<u32> draw_rect{
static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) +
viewport_rect_unscaled.left * res_scale,
surfaces_rect.left, surfaces_rect.right)), // Left
@ -841,9 +841,9 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
}
// Mark framebuffer surfaces as dirty
MathUtil::Rectangle<u32> draw_rect_unscaled{
draw_rect.left / res_scale, draw_rect.top / res_scale, draw_rect.right / res_scale,
draw_rect.bottom / res_scale};
Common::Rectangle<u32> draw_rect_unscaled{draw_rect.left / res_scale, draw_rect.top / res_scale,
draw_rect.right / res_scale,
draw_rect.bottom / res_scale};
if (color_surface != nullptr && write_color_fb) {
auto interval = color_surface->GetSubRectInterval(draw_rect_unscaled);
@ -1392,7 +1392,7 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe
dst_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.output_format);
dst_params.UpdateParams();
MathUtil::Rectangle<u32> src_rect;
Common::Rectangle<u32> src_rect;
Surface src_surface;
std::tie(src_surface, src_rect) =
res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
@ -1401,7 +1401,7 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe
dst_params.res_scale = src_surface->res_scale;
MathUtil::Rectangle<u32> dst_rect;
Common::Rectangle<u32> dst_rect;
Surface dst_surface;
std::tie(dst_surface, dst_rect) =
res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, false);
@ -1461,7 +1461,7 @@ bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon
src_params.size = ((src_params.height - 1) * src_params.stride) + src_params.width;
src_params.end = src_params.addr + src_params.size;
MathUtil::Rectangle<u32> src_rect;
Common::Rectangle<u32> src_rect;
Surface src_surface;
std::tie(src_surface, src_rect) = res_cache.GetTexCopySurface(src_params);
if (src_surface == nullptr) {
@ -1486,7 +1486,7 @@ bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon
// Since we are going to invalidate the gap if there is one, we will have to load it first
const bool load_gap = output_gap != 0;
MathUtil::Rectangle<u32> dst_rect;
Common::Rectangle<u32> dst_rect;
Surface dst_surface;
std::tie(dst_surface, dst_rect) =
res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, load_gap);
@ -1532,7 +1532,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
src_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.color_format);
src_params.UpdateParams();
MathUtil::Rectangle<u32> src_rect;
Common::Rectangle<u32> src_rect;
Surface src_surface;
std::tie(src_surface, src_rect) =
res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
@ -1544,7 +1544,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
u32 scaled_width = src_surface->GetScaledWidth();
u32 scaled_height = src_surface->GetScaledHeight();
screen_info.display_texcoords = MathUtil::Rectangle<float>(
screen_info.display_texcoords = Common::Rectangle<float>(
(float)src_rect.bottom / (float)scaled_height, (float)src_rect.left / (float)scaled_width,
(float)src_rect.top / (float)scaled_height, (float)src_rect.right / (float)scaled_width);

View file

@ -347,8 +347,8 @@ static void AllocateTextureCube(GLuint texture, const FormatTuple& format_tuple,
cur_state.Apply();
}
static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex,
const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type,
static bool BlitTextures(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
const Common::Rectangle<u32>& dst_rect, SurfaceType type,
GLuint read_fb_handle, GLuint draw_fb_handle) {
OpenGLState prev_state = OpenGLState::GetCurState();
SCOPE_EXIT({ prev_state.Apply(); });
@ -407,7 +407,7 @@ static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rec
}
static bool FillSurface(const Surface& surface, const u8* fill_data,
const MathUtil::Rectangle<u32>& fill_rect, GLuint draw_fb_handle) {
const Common::Rectangle<u32>& fill_rect, GLuint draw_fb_handle) {
OpenGLState prev_state = OpenGLState::GetCurState();
SCOPE_EXIT({ prev_state.Apply(); });
@ -431,7 +431,7 @@ static bool FillSurface(const Surface& surface, const u8* fill_data,
Pica::Texture::TextureInfo tex_info{};
tex_info.format = static_cast<Pica::TexturingRegs::TextureFormat>(surface->pixel_format);
Math::Vec4<u8> color = Pica::Texture::LookupTexture(fill_data, 0, 0, tex_info);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(fill_data, 0, 0, tex_info);
std::array<GLfloat, 4> color_values = {color.x / 255.f, color.y / 255.f, color.z / 255.f,
color.w / 255.f};
@ -511,7 +511,7 @@ SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const {
return params;
}
SurfaceInterval SurfaceParams::GetSubRectInterval(MathUtil::Rectangle<u32> unscaled_rect) const {
SurfaceInterval SurfaceParams::GetSubRectInterval(Common::Rectangle<u32> unscaled_rect) const {
if (unscaled_rect.GetHeight() == 0 || unscaled_rect.GetWidth() == 0) {
return {};
}
@ -534,24 +534,24 @@ SurfaceInterval SurfaceParams::GetSubRectInterval(MathUtil::Rectangle<u32> unsca
return {addr + BytesInPixels(pixel_offset), addr + BytesInPixels(pixel_offset + pixels)};
}
MathUtil::Rectangle<u32> SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const {
Common::Rectangle<u32> SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const {
const u32 begin_pixel_index = PixelsInBytes(sub_surface.addr - addr);
if (is_tiled) {
const int x0 = (begin_pixel_index % (stride * 8)) / 8;
const int y0 = (begin_pixel_index / (stride * 8)) * 8;
// Top to bottom
return MathUtil::Rectangle<u32>(x0, height - y0, x0 + sub_surface.width,
height - (y0 + sub_surface.height));
return Common::Rectangle<u32>(x0, height - y0, x0 + sub_surface.width,
height - (y0 + sub_surface.height));
}
const int x0 = begin_pixel_index % stride;
const int y0 = begin_pixel_index / stride;
// Bottom to top
return MathUtil::Rectangle<u32>(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0);
return Common::Rectangle<u32>(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0);
}
MathUtil::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const {
Common::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const {
auto rect = GetSubRect(sub_surface);
rect.left = rect.left * res_scale;
rect.right = rect.right * res_scale;
@ -819,7 +819,7 @@ void CachedSurface::FlushGLBuffer(PAddr flush_start, PAddr flush_end) {
}
MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));
void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle,
void CachedSurface::UploadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle,
GLuint draw_fb_handle) {
if (type == SurfaceType::Fill)
return;
@ -883,7 +883,7 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint
}
MICROPROFILE_DEFINE(OpenGL_TextureDL, "OpenGL", "Texture Download", MP_RGB(128, 192, 64));
void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle,
void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle,
GLuint draw_fb_handle) {
if (type == SurfaceType::Fill)
return;
@ -918,7 +918,7 @@ void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLui
OGLTexture unscaled_tex;
unscaled_tex.Create();
MathUtil::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0};
Common::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0};
AllocateSurfaceTexture(unscaled_tex.handle, tuple, rect.GetWidth(), rect.GetHeight());
BlitTextures(texture.handle, scaled_rect, unscaled_tex.handle, unscaled_tex_rect, type,
read_fb_handle, draw_fb_handle);
@ -1122,9 +1122,9 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64));
bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
const MathUtil::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& src_rect,
const Surface& dst_surface,
const MathUtil::Rectangle<u32>& dst_rect) {
const Common::Rectangle<u32>& dst_rect) {
MICROPROFILE_SCOPE(OpenGL_BlitSurface);
if (!SurfaceParams::CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format))
@ -1138,9 +1138,9 @@ bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
}
void RasterizerCacheOpenGL::ConvertD24S8toABGR(GLuint src_tex,
const MathUtil::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& src_rect,
GLuint dst_tex,
const MathUtil::Rectangle<u32>& dst_rect) {
const Common::Rectangle<u32>& dst_rect) {
OpenGLState prev_state = OpenGLState::GetCurState();
SCOPE_EXIT({ prev_state.Apply(); });
@ -1247,7 +1247,7 @@ SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams&
ScaleMatch match_res_scale,
bool load_if_create) {
if (params.addr == 0 || params.height * params.width == 0) {
return std::make_tuple(nullptr, MathUtil::Rectangle<u32>{});
return std::make_tuple(nullptr, Common::Rectangle<u32>{});
}
// Attempt to find encompassing surface
@ -1340,7 +1340,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Pica::Texture::TextureInf
if (info.width % 8 != 0 || info.height % 8 != 0) {
Surface src_surface;
MathUtil::Rectangle<u32> rect;
Common::Rectangle<u32> rect;
std::tie(src_surface, rect) = GetSurfaceSubRect(params, ScaleMatch::Ignore, true);
params.res_scale = src_surface->res_scale;
@ -1447,7 +1447,7 @@ const CachedTextureCube& RasterizerCacheOpenGL::GetTextureCube(const TextureCube
}
SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport_rect) {
bool using_color_fb, bool using_depth_fb, const Common::Rectangle<s32>& viewport_rect) {
const auto& regs = Pica::g_state.regs;
const auto& config = regs.framebuffer.framebuffer;
@ -1461,7 +1461,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
texture_cube_cache.clear();
}
MathUtil::Rectangle<u32> viewport_clamped{
Common::Rectangle<u32> viewport_clamped{
static_cast<u32>(std::clamp(viewport_rect.left, 0, static_cast<s32>(config.GetWidth()))),
static_cast<u32>(std::clamp(viewport_rect.top, 0, static_cast<s32>(config.GetHeight()))),
static_cast<u32>(std::clamp(viewport_rect.right, 0, static_cast<s32>(config.GetWidth()))),
@ -1495,19 +1495,19 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
using_depth_fb = false;
}
MathUtil::Rectangle<u32> color_rect{};
Common::Rectangle<u32> color_rect{};
Surface color_surface = nullptr;
if (using_color_fb)
std::tie(color_surface, color_rect) =
GetSurfaceSubRect(color_params, ScaleMatch::Exact, false);
MathUtil::Rectangle<u32> depth_rect{};
Common::Rectangle<u32> depth_rect{};
Surface depth_surface = nullptr;
if (using_depth_fb)
std::tie(depth_surface, depth_rect) =
GetSurfaceSubRect(depth_params, ScaleMatch::Exact, false);
MathUtil::Rectangle<u32> fb_rect{};
Common::Rectangle<u32> fb_rect{};
if (color_surface != nullptr && depth_surface != nullptr) {
fb_rect = color_rect;
// Color and Depth surfaces must have the same dimensions and offsets
@ -1560,7 +1560,7 @@ Surface RasterizerCacheOpenGL::GetFillSurface(const GPU::Regs::MemoryFillConfig&
}
SurfaceRect_Tuple RasterizerCacheOpenGL::GetTexCopySurface(const SurfaceParams& params) {
MathUtil::Rectangle<u32> rect{};
Common::Rectangle<u32> rect{};
Surface match_surface = FindMatch<MatchFlags::TexCopy | MatchFlags::Invalid>(
surface_cache, params, ScaleMatch::Ignore);

View file

@ -88,8 +88,8 @@ static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval
std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(),
"incorrect interval types");
using SurfaceRect_Tuple = std::tuple<Surface, MathUtil::Rectangle<u32>>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>;
using SurfaceRect_Tuple = std::tuple<Surface, Common::Rectangle<u32>>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>;
using PageMap = boost::icl::interval_map<u32, int>;
@ -250,7 +250,7 @@ struct SurfaceParams {
// Returns the outer rectangle containing "interval"
SurfaceParams FromInterval(SurfaceInterval interval) const;
SurfaceInterval GetSubRectInterval(MathUtil::Rectangle<u32> unscaled_rect) const;
SurfaceInterval GetSubRectInterval(Common::Rectangle<u32> unscaled_rect) const;
// Returns the region of the biggest valid rectange within interval
SurfaceInterval GetCopyableInterval(const Surface& src_surface) const;
@ -263,11 +263,11 @@ struct SurfaceParams {
return height * res_scale;
}
MathUtil::Rectangle<u32> GetRect() const {
Common::Rectangle<u32> GetRect() const {
return {0, height, width, 0};
}
MathUtil::Rectangle<u32> GetScaledRect() const {
Common::Rectangle<u32> GetScaledRect() const {
return {0, GetScaledHeight(), GetScaledWidth(), 0};
}
@ -284,8 +284,8 @@ struct SurfaceParams {
bool CanExpand(const SurfaceParams& expanded_surface) const;
bool CanTexCopy(const SurfaceParams& texcopy_params) const;
MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const;
MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const;
Common::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const;
Common::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const;
PAddr addr = 0;
PAddr end = 0;
@ -373,9 +373,9 @@ struct CachedSurface : SurfaceParams, std::enable_shared_from_this<CachedSurface
void FlushGLBuffer(PAddr flush_start, PAddr flush_end);
// Upload/Download data in gl_buffer in/to this surface's texture
void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle,
void UploadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle,
GLuint draw_fb_handle);
void DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle,
void DownloadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle,
GLuint draw_fb_handle);
std::shared_ptr<SurfaceWatcher> CreateWatcher() {
@ -413,11 +413,11 @@ public:
~RasterizerCacheOpenGL();
/// Blit one surface's texture to another
bool BlitSurfaces(const Surface& src_surface, const MathUtil::Rectangle<u32>& src_rect,
const Surface& dst_surface, const MathUtil::Rectangle<u32>& dst_rect);
bool BlitSurfaces(const Surface& src_surface, const Common::Rectangle<u32>& src_rect,
const Surface& dst_surface, const Common::Rectangle<u32>& dst_rect);
void ConvertD24S8toABGR(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect,
GLuint dst_tex, const MathUtil::Rectangle<u32>& dst_rect);
void ConvertD24S8toABGR(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
const Common::Rectangle<u32>& dst_rect);
/// Copy one surface's region to another
void CopySurface(const Surface& src_surface, const Surface& dst_surface,
@ -441,7 +441,7 @@ public:
/// Get the color and depth surfaces based on the framebuffer configuration
SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
const MathUtil::Rectangle<s32>& viewport_rect);
const Common::Rectangle<s32>& viewport_rect);
/// Get a surface that matches the fill config
Surface GetFillSurface(const GPU::Regs::MemoryFillConfig& config);

View file

@ -221,7 +221,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
static_cast<u32>(pixel_stride), screen_info)) {
// Reset the screen info's display texture to its own permanent texture
screen_info.display_texture = screen_info.texture.resource.handle;
screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
screen_info.display_texcoords = Common::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
Memory::RasterizerFlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height);

View file

@ -32,7 +32,7 @@ struct TextureInfo {
/// Structure used for storing information about the display target for each 3DS screen
struct ScreenInfo {
GLuint display_texture;
MathUtil::Rectangle<float> display_texcoords;
Common::Rectangle<float> display_texcoords;
TextureInfo texture;
};

View file

@ -54,18 +54,18 @@ struct DebugData<true> {
LOOP_INT_IN = 0x800,
};
Math::Vec4<float24> src1;
Math::Vec4<float24> src2;
Math::Vec4<float24> src3;
Common::Vec4<float24> src1;
Common::Vec4<float24> src2;
Common::Vec4<float24> src3;
Math::Vec4<float24> dest_in;
Math::Vec4<float24> dest_out;
Common::Vec4<float24> dest_in;
Common::Vec4<float24> dest_out;
s32 address_registers[2];
bool conditional_code[2];
bool cond_bool;
bool cond_cmp[2];
Math::Vec4<u8> loop_int;
Common::Vec4<u8> loop_int;
u32 instruction_offset;
u32 next_instruction;
@ -152,7 +152,8 @@ inline void SetField<DebugDataRecord::COND_CMP_IN>(DebugDataRecord& record, bool
}
template <>
inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Math::Vec4<u8> value) {
inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record,
Common::Vec4<u8> value) {
record.loop_int = value;
}

View file

@ -85,7 +85,7 @@ void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input
}
}
static void CopyRegistersToOutput(const Math::Vec4<float24>* regs, u32 mask,
static void CopyRegistersToOutput(const Common::Vec4<float24>* regs, u32 mask,
AttributeBuffer& buffer) {
int output_i = 0;
for (int reg : Common::BitSet<u32>(mask)) {
@ -107,7 +107,7 @@ GSEmitter::~GSEmitter() {
delete handlers;
}
void GSEmitter::Emit(Math::Vec4<float24> (&output_regs)[16]) {
void GSEmitter::Emit(Common::Vec4<float24> (&output_regs)[16]) {
ASSERT(vertex_id < 3);
// TODO: This should be merged with UnitState::WriteOutput somehow
CopyRegistersToOutput(output_regs, output_mask, buffer[vertex_id]);

View file

@ -28,7 +28,7 @@ constexpr unsigned MAX_PROGRAM_CODE_LENGTH = 4096;
constexpr unsigned MAX_SWIZZLE_DATA_LENGTH = 4096;
struct AttributeBuffer {
alignas(16) Math::Vec4<float24> attr[16];
alignas(16) Common::Vec4<float24> attr[16];
};
/// Handler type for receiving vertex outputs from vertex shader or geometry shader
@ -38,16 +38,16 @@ using VertexHandler = std::function<void(const AttributeBuffer&)>;
using WindingSetter = std::function<void()>;
struct OutputVertex {
Math::Vec4<float24> pos;
Math::Vec4<float24> quat;
Math::Vec4<float24> color;
Math::Vec2<float24> tc0;
Math::Vec2<float24> tc1;
Common::Vec4<float24> pos;
Common::Vec4<float24> quat;
Common::Vec4<float24> color;
Common::Vec2<float24> tc0;
Common::Vec2<float24> tc1;
float24 tc0_w;
INSERT_PADDING_WORDS(1);
Math::Vec3<float24> view;
Common::Vec3<float24> view;
INSERT_PADDING_WORDS(1);
Math::Vec2<float24> tc2;
Common::Vec2<float24> tc2;
static void ValidateSemantics(const RasterizerRegs& regs);
static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs,
@ -87,7 +87,7 @@ struct GSEmitter {
GSEmitter();
~GSEmitter();
void Emit(Math::Vec4<float24> (&output_regs)[16]);
void Emit(Common::Vec4<float24> (&output_regs)[16]);
};
static_assert(std::is_standard_layout<GSEmitter>::value, "GSEmitter is not standard layout type");
@ -102,9 +102,9 @@ struct UnitState {
struct Registers {
// The registers are accessed by the shader JIT using SSE instructions, and are therefore
// required to be 16-byte aligned.
alignas(16) Math::Vec4<float24> input[16];
alignas(16) Math::Vec4<float24> temporary[16];
alignas(16) Math::Vec4<float24> output[16];
alignas(16) Common::Vec4<float24> input[16];
alignas(16) Common::Vec4<float24> temporary[16];
alignas(16) Common::Vec4<float24> output[16];
} registers;
static_assert(std::is_pod<Registers>::value, "Structure is not POD");
@ -120,11 +120,11 @@ struct UnitState {
switch (reg.GetRegisterType()) {
case RegisterType::Input:
return offsetof(UnitState, registers.input) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
case RegisterType::Temporary:
return offsetof(UnitState, registers.temporary) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
default:
UNREACHABLE();
@ -136,11 +136,11 @@ struct UnitState {
switch (reg.GetRegisterType()) {
case RegisterType::Output:
return offsetof(UnitState, registers.output) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
case RegisterType::Temporary:
return offsetof(UnitState, registers.temporary) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
default:
UNREACHABLE();
@ -175,13 +175,13 @@ struct GSUnitState : public UnitState {
struct Uniforms {
// The float uniforms are accessed by the shader JIT using SSE instructions, and are
// therefore required to be 16-byte aligned.
alignas(16) Math::Vec4<float24> f[96];
alignas(16) Common::Vec4<float24> f[96];
std::array<bool, 16> b;
std::array<Math::Vec4<u8>, 4> i;
std::array<Common::Vec4<u8>, 4> i;
static std::size_t GetFloatUniformOffset(unsigned index) {
return offsetof(Uniforms, f) + index * sizeof(Math::Vec4<float24>);
return offsetof(Uniforms, f) + index * sizeof(Common::Vec4<float24>);
}
static std::size_t GetBoolUniformOffset(unsigned index) {
@ -189,7 +189,7 @@ struct Uniforms {
}
static std::size_t GetIntUniformOffset(unsigned index) {
return offsetof(Uniforms, i) + index * sizeof(Math::Vec4<u8>);
return offsetof(Uniforms, i) + index * sizeof(Common::Vec4<u8>);
}
};

View file

@ -622,10 +622,10 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
}
case OpCode::Id::LOOP: {
Math::Vec4<u8> loop_param(uniforms.i[instr.flow_control.int_uniform_id].x,
uniforms.i[instr.flow_control.int_uniform_id].y,
uniforms.i[instr.flow_control.int_uniform_id].z,
uniforms.i[instr.flow_control.int_uniform_id].w);
Common::Vec4<u8> loop_param(uniforms.i[instr.flow_control.int_uniform_id].x,
uniforms.i[instr.flow_control.int_uniform_id].y,
uniforms.i[instr.flow_control.int_uniform_id].z,
uniforms.i[instr.flow_control.int_uniform_id].w);
state.address_registers[2] = loop_param.y;
Record<DebugDataRecord::LOOP_INT_IN>(debug_data, iteration, loop_param);
@ -688,7 +688,7 @@ DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup,
DebugData<true> debug_data;
// Setup input register table
boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero()));
boost::fill(state.registers.input, Common::Vec4<float24>::AssignToAll(float24::Zero()));
state.LoadInput(config, input);
RunInterpreter(setup, state, debug_data, setup.engine_data.entry_point);
return debug_data;

View file

@ -777,7 +777,7 @@ void JitShader::Compile_JMP(Instruction instr) {
}
}
static void Emit(GSEmitter* emitter, Math::Vec4<float24> (*output)[16]) {
static void Emit(GSEmitter* emitter, Common::Vec4<float24> (*output)[16]) {
emitter->Emit(*output);
}

View file

@ -23,13 +23,15 @@ namespace Pica::Clipper {
struct ClippingEdge {
public:
ClippingEdge(Math::Vec4<float24> coeffs, Math::Vec4<float24> bias = Math::Vec4<float24>(
float24::FromFloat32(0), float24::FromFloat32(0),
float24::FromFloat32(0), float24::FromFloat32(0)))
ClippingEdge(Common::Vec4<float24> coeffs,
Common::Vec4<float24> bias = Common::Vec4<float24>(float24::FromFloat32(0),
float24::FromFloat32(0),
float24::FromFloat32(0),
float24::FromFloat32(0)))
: coeffs(coeffs), bias(bias) {}
bool IsInside(const Vertex& vertex) const {
return Math::Dot(vertex.pos + bias, coeffs) >= float24::FromFloat32(0);
return Common::Dot(vertex.pos + bias, coeffs) >= float24::FromFloat32(0);
}
bool IsOutSide(const Vertex& vertex) const {
@ -37,8 +39,8 @@ public:
}
Vertex GetIntersection(const Vertex& v0, const Vertex& v1) const {
float24 dp = Math::Dot(v0.pos + bias, coeffs);
float24 dp_prev = Math::Dot(v1.pos + bias, coeffs);
float24 dp = Common::Dot(v0.pos + bias, coeffs);
float24 dp_prev = Common::Dot(v1.pos + bias, coeffs);
float24 factor = dp_prev / (dp_prev - dp);
return Vertex::Lerp(factor, v0, v1);
@ -46,8 +48,8 @@ public:
private:
float24 pos;
Math::Vec4<float24> coeffs;
Math::Vec4<float24> bias;
Common::Vec4<float24> coeffs;
Common::Vec4<float24> bias;
};
static void InitScreenCoordinates(Vertex& vtx) {
@ -95,7 +97,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
static_vector<Vertex, MAX_VERTICES> buffer_b;
auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) {
if (Math::Dot(a, b) < float24::Zero())
if (Common::Dot(a, b) < float24::Zero())
a = a * float24::FromFloat32(-1.0f);
};
@ -114,13 +116,14 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
static const float24 f0 = float24::FromFloat32(0.0);
static const float24 f1 = float24::FromFloat32(1.0);
static const std::array<ClippingEdge, 7> clipping_edges = {{
{Math::MakeVec(-f1, f0, f0, f1)}, // x = +w
{Math::MakeVec(f1, f0, f0, f1)}, // x = -w
{Math::MakeVec(f0, -f1, f0, f1)}, // y = +w
{Math::MakeVec(f0, f1, f0, f1)}, // y = -w
{Math::MakeVec(f0, f0, -f1, f0)}, // z = 0
{Math::MakeVec(f0, f0, f1, f1)}, // z = -w
{Math::MakeVec(f0, f0, f0, f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
{Common::MakeVec(-f1, f0, f0, f1)}, // x = +w
{Common::MakeVec(f1, f0, f0, f1)}, // x = -w
{Common::MakeVec(f0, -f1, f0, f1)}, // y = +w
{Common::MakeVec(f0, f1, f0, f1)}, // y = -w
{Common::MakeVec(f0, f0, -f1, f0)}, // z = 0
{Common::MakeVec(f0, f0, f1, f1)}, // z = -w
{Common::MakeVec(f0, f0, f0, f1),
Common::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
}};
// Simple implementation of the Sutherland-Hodgman clipping algorithm.

View file

@ -18,7 +18,7 @@
namespace Pica::Rasterizer {
void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
void DrawPixel(int x, int y, const Common::Vec4<u8>& color) {
const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
@ -61,7 +61,7 @@ void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
}
}
const Math::Vec4<u8> GetPixel(int x, int y) {
const Common::Vec4<u8> GetPixel(int x, int y) {
const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
@ -257,10 +257,12 @@ u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u
}
}
Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation) {
Math::Vec4<int> result;
Common::Vec4<u8> EvaluateBlendEquation(const Common::Vec4<u8>& src,
const Common::Vec4<u8>& srcfactor,
const Common::Vec4<u8>& dest,
const Common::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation) {
Common::Vec4<int> result;
auto src_result = (src * srcfactor).Cast<int>();
auto dst_result = (dest * destfactor).Cast<int>();
@ -299,8 +301,8 @@ Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4
UNIMPLEMENTED();
}
return Math::Vec4<u8>(std::clamp(result.r(), 0, 255), std::clamp(result.g(), 0, 255),
std::clamp(result.b(), 0, 255), std::clamp(result.a(), 0, 255));
return Common::Vec4<u8>(std::clamp(result.r(), 0, 255), std::clamp(result.g(), 0, 255),
std::clamp(result.b(), 0, 255), std::clamp(result.a(), 0, 255));
};
u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) {
@ -359,7 +361,7 @@ u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) {
// Decode/Encode for shadow map format. It is similar to D24S8 format, but the depth field is in
// big-endian
static const Math::Vec2<u32> DecodeD24S8Shadow(const u8* bytes) {
static const Common::Vec2<u32> DecodeD24S8Shadow(const u8* bytes) {
return {static_cast<u32>((bytes[0] << 16) | (bytes[1] << 8) | bytes[2]), bytes[3]};
}

View file

@ -10,17 +10,19 @@
namespace Pica::Rasterizer {
void DrawPixel(int x, int y, const Math::Vec4<u8>& color);
const Math::Vec4<u8> GetPixel(int x, int y);
void DrawPixel(int x, int y, const Common::Vec4<u8>& color);
const Common::Vec4<u8> GetPixel(int x, int y);
u32 GetDepth(int x, int y);
u8 GetStencil(int x, int y);
void SetDepth(int x, int y, u32 value);
void SetStencil(int x, int y, u8 value);
u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref);
Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation);
Common::Vec4<u8> EvaluateBlendEquation(const Common::Vec4<u8>& src,
const Common::Vec4<u8>& srcfactor,
const Common::Vec4<u8>& dest,
const Common::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation);
u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op);

View file

@ -20,63 +20,63 @@ static float LookupLightingLut(const Pica::State::Lighting& lighting, std::size_
return lut_value + lut_diff * delta;
}
std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
std::tuple<Common::Vec4<u8>, Common::Vec4<u8>> ComputeFragmentsColors(
const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state,
const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view,
const Math::Vec4<u8> (&texture_color)[4]) {
const Common::Quaternion<float>& normquat, const Common::Vec3<float>& view,
const Common::Vec4<u8> (&texture_color)[4]) {
Math::Vec4<float> shadow;
Common::Vec4<float> shadow;
if (lighting.config0.enable_shadow) {
shadow = texture_color[lighting.config0.shadow_selector].Cast<float>() / 255.0f;
if (lighting.config0.shadow_invert) {
shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow;
shadow = Common::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow;
}
} else {
shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f);
shadow = Common::MakeVec(1.0f, 1.0f, 1.0f, 1.0f);
}
Math::Vec3<float> surface_normal;
Math::Vec3<float> surface_tangent;
Common::Vec3<float> surface_normal;
Common::Vec3<float> surface_tangent;
if (lighting.config0.bump_mode != LightingRegs::LightingBumpMode::None) {
Math::Vec3<float> perturbation =
Common::Vec3<float> perturbation =
texture_color[lighting.config0.bump_selector].xyz().Cast<float>() / 127.5f -
Math::MakeVec(1.0f, 1.0f, 1.0f);
Common::MakeVec(1.0f, 1.0f, 1.0f);
if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
if (!lighting.config0.disable_bump_renorm) {
const float z_square = 1 - perturbation.xy().Length2();
perturbation.z = std::sqrt(std::max(z_square, 0.0f));
}
surface_normal = perturbation;
surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f);
surface_tangent = Common::MakeVec(1.0f, 0.0f, 0.0f);
} else if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::TangentMap) {
surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f);
surface_normal = Common::MakeVec(0.0f, 0.0f, 1.0f);
surface_tangent = perturbation;
} else {
LOG_ERROR(HW_GPU, "Unknown bump mode {}",
static_cast<u32>(lighting.config0.bump_mode.Value()));
}
} else {
surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f);
surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f);
surface_normal = Common::MakeVec(0.0f, 0.0f, 1.0f);
surface_tangent = Common::MakeVec(1.0f, 0.0f, 0.0f);
}
// Use the normalized the quaternion when performing the rotation
auto normal = Math::QuaternionRotate(normquat, surface_normal);
auto tangent = Math::QuaternionRotate(normquat, surface_tangent);
auto normal = Common::QuaternionRotate(normquat, surface_normal);
auto tangent = Common::QuaternionRotate(normquat, surface_tangent);
Math::Vec4<float> diffuse_sum = {0.0f, 0.0f, 0.0f, 1.0f};
Math::Vec4<float> specular_sum = {0.0f, 0.0f, 0.0f, 1.0f};
Common::Vec4<float> diffuse_sum = {0.0f, 0.0f, 0.0f, 1.0f};
Common::Vec4<float> specular_sum = {0.0f, 0.0f, 0.0f, 1.0f};
for (unsigned light_index = 0; light_index <= lighting.max_light_index; ++light_index) {
unsigned num = lighting.light_enable.GetNum(light_index);
const auto& light_config = lighting.light[num];
Math::Vec3<float> refl_value = {};
Math::Vec3<float> position = {float16::FromRaw(light_config.x).ToFloat32(),
float16::FromRaw(light_config.y).ToFloat32(),
float16::FromRaw(light_config.z).ToFloat32()};
Math::Vec3<float> light_vector;
Common::Vec3<float> refl_value = {};
Common::Vec3<float> position = {float16::FromRaw(light_config.x).ToFloat32(),
float16::FromRaw(light_config.y).ToFloat32(),
float16::FromRaw(light_config.z).ToFloat32()};
Common::Vec3<float> light_vector;
if (light_config.config.directional)
light_vector = position;
@ -85,8 +85,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
light_vector.Normalize();
Math::Vec3<float> norm_view = view.Normalized();
Math::Vec3<float> half_vector = norm_view + light_vector;
Common::Vec3<float> norm_view = view.Normalized();
Common::Vec3<float> half_vector = norm_view + light_vector;
float dist_atten = 1.0f;
if (!lighting.IsDistAttenDisabled(num)) {
@ -111,33 +111,33 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
switch (input) {
case LightingRegs::LightingLutInput::NH:
result = Math::Dot(normal, half_vector.Normalized());
result = Common::Dot(normal, half_vector.Normalized());
break;
case LightingRegs::LightingLutInput::VH:
result = Math::Dot(norm_view, half_vector.Normalized());
result = Common::Dot(norm_view, half_vector.Normalized());
break;
case LightingRegs::LightingLutInput::NV:
result = Math::Dot(normal, norm_view);
result = Common::Dot(normal, norm_view);
break;
case LightingRegs::LightingLutInput::LN:
result = Math::Dot(light_vector, normal);
result = Common::Dot(light_vector, normal);
break;
case LightingRegs::LightingLutInput::SP: {
Math::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
light_config.spot_z.Value()};
result = Math::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
Common::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
light_config.spot_z.Value()};
result = Common::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
break;
}
case LightingRegs::LightingLutInput::CP:
if (lighting.config0.config == LightingRegs::LightingConfig::Config7) {
const Math::Vec3<float> norm_half_vector = half_vector.Normalized();
const Math::Vec3<float> half_vector_proj =
norm_half_vector - normal * Math::Dot(normal, norm_half_vector);
result = Math::Dot(half_vector_proj, tangent);
const Common::Vec3<float> norm_half_vector = half_vector.Normalized();
const Common::Vec3<float> half_vector_proj =
norm_half_vector - normal * Common::Dot(normal, norm_half_vector);
result = Common::Dot(half_vector_proj, tangent);
} else {
result = 0.0f;
}
@ -192,7 +192,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
lighting.lut_scale.d0, LightingRegs::LightingSampler::Distribution0);
}
Math::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f();
Common::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f();
// If enabled, lookup ReflectRed value, otherwise, 1.0 is used
if (lighting.config1.disable_lut_rr == 0 &&
@ -237,7 +237,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
lighting.lut_scale.d1, LightingRegs::LightingSampler::Distribution1);
}
Math::Vec3<float> specular_1 =
Common::Vec3<float> specular_1 =
d1_lut_value * refl_value * light_config.specular_1.ToVec3f();
// Fresnel
@ -261,7 +261,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
}
}
auto dot_product = Math::Dot(light_vector, normal);
auto dot_product = Common::Dot(light_vector, normal);
if (light_config.config.two_sided_diffuse)
dot_product = std::abs(dot_product);
else
@ -297,8 +297,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
}
}
diffuse_sum += Math::MakeVec(diffuse, 0.0f);
specular_sum += Math::MakeVec(specular, 0.0f);
diffuse_sum += Common::MakeVec(diffuse, 0.0f);
specular_sum += Common::MakeVec(specular, 0.0f);
}
if (lighting.config0.shadow_alpha) {
@ -314,17 +314,17 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
}
}
diffuse_sum += Math::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);
diffuse_sum += Common::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);
auto diffuse = Math::MakeVec<float>(std::clamp(diffuse_sum.x, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.y, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.z, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.w, 0.0f, 1.0f) * 255)
auto diffuse = Common::MakeVec<float>(std::clamp(diffuse_sum.x, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.y, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.z, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.w, 0.0f, 1.0f) * 255)
.Cast<u8>();
auto specular = Math::MakeVec<float>(std::clamp(specular_sum.x, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.y, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.z, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.w, 0.0f, 1.0f) * 255)
auto specular = Common::MakeVec<float>(std::clamp(specular_sum.x, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.y, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.z, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.w, 0.0f, 1.0f) * 255)
.Cast<u8>();
return std::make_tuple(diffuse, specular);
}

View file

@ -11,9 +11,9 @@
namespace Pica {
std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
std::tuple<Common::Vec4<u8>, Common::Vec4<u8>> ComputeFragmentsColors(
const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state,
const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view,
const Math::Vec4<u8> (&texture_color)[4]);
const Common::Quaternion<float>& normquat, const Common::Vec3<float>& view,
const Common::Vec4<u8> (&texture_color)[4]);
} // namespace Pica

View file

@ -63,7 +63,7 @@ static float NoiseCoef(float u, float v, TexturingRegs regs, State::ProcTex stat
const float g3 = NoiseRand2D(x_int + 1, y_int + 1) * (x_frac + y_frac - 2);
const float x_noise = LookupLUT(state.noise_table, x_frac);
const float y_noise = LookupLUT(state.noise_table, y_frac);
return Math::BilinearInterp(g0, g1, g2, g3, x_noise, y_noise);
return Common::BilinearInterp(g0, g1, g2, g3, x_noise, y_noise);
}
static float GetShiftOffset(float v, ProcTexShift mode, ProcTexClamp clamp_mode) {
@ -154,7 +154,7 @@ float CombineAndMap(float u, float v, ProcTexCombiner combiner,
return LookupLUT(map_table, f);
}
Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state) {
Common::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state) {
u = std::abs(u);
v = std::abs(v);
@ -187,7 +187,7 @@ Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex stat
const u32 offset = regs.proctex_lut_offset.level0;
const u32 width = regs.proctex_lut.width;
const float index = offset + (lut_coord * (width - 1));
Math::Vec4<u8> final_color;
Common::Vec4<u8> final_color;
// TODO(wwylele): implement mipmap
switch (regs.proctex_lut.filter) {
case ProcTexFilter::Linear:
@ -212,7 +212,7 @@ Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex stat
// uses the output of CombineAndMap directly instead.
const float final_alpha =
CombineAndMap(u, v, regs.proctex.alpha_combiner, state.alpha_map_table);
return Math::MakeVec<u8>(final_color.rgb(), static_cast<u8>(final_alpha * 255));
return Common::MakeVec<u8>(final_color.rgb(), static_cast<u8>(final_alpha * 255));
} else {
return final_color;
}

View file

@ -9,6 +9,6 @@
namespace Pica::Rasterizer {
/// Generates procedural texture color for the given coordinates
Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state);
Common::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state);
} // namespace Pica::Rasterizer

View file

@ -64,12 +64,12 @@ private:
*
* @todo define orientation concretely.
*/
static int SignedArea(const Math::Vec2<Fix12P4>& vtx1, const Math::Vec2<Fix12P4>& vtx2,
const Math::Vec2<Fix12P4>& vtx3) {
const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0);
const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0);
static int SignedArea(const Common::Vec2<Fix12P4>& vtx1, const Common::Vec2<Fix12P4>& vtx2,
const Common::Vec2<Fix12P4>& vtx3) {
const auto vec1 = Common::MakeVec(vtx2 - vtx1, 0);
const auto vec2 = Common::MakeVec(vtx3 - vtx1, 0);
// TODO: There is a very small chance this will overflow for sizeof(int) == 4
return Math::Cross(vec1, vec2).z;
return Common::Cross(vec1, vec2).z;
};
/// Convert a 3D vector for cube map coordinates to 2D texture coordinates along with the face name
@ -134,13 +134,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// triangle borders. Is it that the correct solution, though?
return Fix12P4(static_cast<unsigned short>(round(flt.ToFloat32() * 16.0f)));
};
static auto ScreenToRasterizerCoordinates = [](const Math::Vec3<float24>& vec) {
return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
static auto ScreenToRasterizerCoordinates = [](const Common::Vec3<float24>& vec) {
return Common::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
};
Math::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos),
ScreenToRasterizerCoordinates(v1.screenpos),
ScreenToRasterizerCoordinates(v2.screenpos)};
Common::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos),
ScreenToRasterizerCoordinates(v1.screenpos),
ScreenToRasterizerCoordinates(v2.screenpos)};
if (regs.rasterizer.cull_mode == RasterizerRegs::CullMode::KeepAll) {
// Make sure we always end up with a triangle wound counter-clockwise
@ -189,9 +189,9 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// drawn. Pixels on any other triangle border are drawn. This is implemented with three bias
// values which are added to the barycentric coordinates w0, w1 and w2, respectively.
// NOTE: These are the PSP filling rules. Not sure if the 3DS uses the same ones...
auto IsRightSideOrFlatBottomEdge = [](const Math::Vec2<Fix12P4>& vtx,
const Math::Vec2<Fix12P4>& line1,
const Math::Vec2<Fix12P4>& line2) {
auto IsRightSideOrFlatBottomEdge = [](const Common::Vec2<Fix12P4>& vtx,
const Common::Vec2<Fix12P4>& line1,
const Common::Vec2<Fix12P4>& line2) {
if (line1.y == line2.y) {
// just check if vertex is above us => bottom line parallel to x-axis
return vtx.y < line1.y;
@ -210,7 +210,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
int bias2 =
IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0;
auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w);
auto w_inverse = Common::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w);
auto textures = regs.texturing.GetTextures();
auto tev_stages = regs.texturing.GetTevStages();
@ -243,11 +243,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
continue;
auto baricentric_coordinates =
Math::MakeVec(float24::FromFloat32(static_cast<float>(w0)),
float24::FromFloat32(static_cast<float>(w1)),
float24::FromFloat32(static_cast<float>(w2)));
Common::MakeVec(float24::FromFloat32(static_cast<float>(w0)),
float24::FromFloat32(static_cast<float>(w1)),
float24::FromFloat32(static_cast<float>(w2)));
float24 interpolated_w_inverse =
float24::FromFloat32(1.0f) / Math::Dot(w_inverse, baricentric_coordinates);
float24::FromFloat32(1.0f) / Common::Dot(w_inverse, baricentric_coordinates);
// interpolated_z = z / w
float interpolated_z_over_w =
@ -288,12 +288,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
//
// The generalization to three vertices is straightforward in baricentric coordinates.
auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) {
auto attr_over_w = Math::MakeVec(attr0, attr1, attr2);
float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates);
auto attr_over_w = Common::MakeVec(attr0, attr1, attr2);
float24 interpolated_attr_over_w =
Common::Dot(attr_over_w, baricentric_coordinates);
return interpolated_attr_over_w * interpolated_w_inverse;
};
Math::Vec4<u8> primary_color{
Common::Vec4<u8> primary_color{
static_cast<u8>(round(
GetInterpolatedAttribute(v0.color.r(), v1.color.r(), v2.color.r()).ToFloat32() *
255)),
@ -308,7 +309,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
255)),
};
Math::Vec2<float24> uv[3];
Common::Vec2<float24> uv[3];
uv[0].u() = GetInterpolatedAttribute(v0.tc0.u(), v1.tc0.u(), v2.tc0.u());
uv[0].v() = GetInterpolatedAttribute(v0.tc0.v(), v1.tc0.v(), v2.tc0.v());
uv[1].u() = GetInterpolatedAttribute(v0.tc1.u(), v1.tc1.u(), v2.tc1.u());
@ -316,7 +317,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
uv[2].u() = GetInterpolatedAttribute(v0.tc2.u(), v1.tc2.u(), v2.tc2.u());
uv[2].v() = GetInterpolatedAttribute(v0.tc2.v(), v1.tc2.v(), v2.tc2.v());
Math::Vec4<u8> texture_color[4]{};
Common::Vec4<u8> texture_color[4]{};
for (int i = 0; i < 3; ++i) {
const auto& texture = textures[i];
if (!texture.enabled)
@ -391,9 +392,10 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
if (use_border_s || use_border_t) {
auto border_color = texture.config.border_color;
texture_color[i] = Math::MakeVec(border_color.r.Value(), border_color.g.Value(),
border_color.b.Value(), border_color.a.Value())
.Cast<u8>();
texture_color[i] =
Common::MakeVec(border_color.r.Value(), border_color.g.Value(),
border_color.b.Value(), border_color.a.Value())
.Cast<u8>();
} else {
// Textures are laid out from bottom to top, hence we invert the t coordinate.
// NOTE: This may not be the right place for the inversion.
@ -442,21 +444,21 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// operations on each of them (e.g. inversion) and then calculate the output color
// with some basic arithmetic. Alpha combiners can be configured separately but work
// analogously.
Math::Vec4<u8> combiner_output;
Math::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
Math::Vec4<u8> next_combiner_buffer =
Math::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
regs.texturing.tev_combiner_buffer_color.g.Value(),
regs.texturing.tev_combiner_buffer_color.b.Value(),
regs.texturing.tev_combiner_buffer_color.a.Value())
Common::Vec4<u8> combiner_output;
Common::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
Common::Vec4<u8> next_combiner_buffer =
Common::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
regs.texturing.tev_combiner_buffer_color.g.Value(),
regs.texturing.tev_combiner_buffer_color.b.Value(),
regs.texturing.tev_combiner_buffer_color.a.Value())
.Cast<u8>();
Math::Vec4<u8> primary_fragment_color = {0, 0, 0, 0};
Math::Vec4<u8> secondary_fragment_color = {0, 0, 0, 0};
Common::Vec4<u8> primary_fragment_color = {0, 0, 0, 0};
Common::Vec4<u8> secondary_fragment_color = {0, 0, 0, 0};
if (!g_state.regs.lighting.disable) {
Math::Quaternion<float> normquat =
Math::Quaternion<float>{
Common::Quaternion<float> normquat =
Common::Quaternion<float>{
{GetInterpolatedAttribute(v0.quat.x, v1.quat.x, v2.quat.x).ToFloat32(),
GetInterpolatedAttribute(v0.quat.y, v1.quat.y, v2.quat.y).ToFloat32(),
GetInterpolatedAttribute(v0.quat.z, v1.quat.z, v2.quat.z).ToFloat32()},
@ -464,7 +466,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
}
.Normalized();
Math::Vec3<float> view{
Common::Vec3<float> view{
GetInterpolatedAttribute(v0.view.x, v1.view.x, v2.view.x).ToFloat32(),
GetInterpolatedAttribute(v0.view.y, v1.view.y, v2.view.y).ToFloat32(),
GetInterpolatedAttribute(v0.view.z, v1.view.z, v2.view.z).ToFloat32(),
@ -478,7 +480,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
const auto& tev_stage = tev_stages[tev_stage_index];
using Source = TexturingRegs::TevStageConfig::Source;
auto GetSource = [&](Source source) -> Math::Vec4<u8> {
auto GetSource = [&](Source source) -> Common::Vec4<u8> {
switch (source) {
case Source::PrimaryColor:
return primary_color;
@ -505,8 +507,8 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
return combiner_buffer;
case Source::Constant:
return Math::MakeVec(tev_stage.const_r.Value(), tev_stage.const_g.Value(),
tev_stage.const_b.Value(), tev_stage.const_a.Value())
return Common::MakeVec(tev_stage.const_r.Value(), tev_stage.const_g.Value(),
tev_stage.const_b.Value(), tev_stage.const_a.Value())
.Cast<u8>();
case Source::Previous:
@ -524,7 +526,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// stage as input. Hence, we currently don't directly write the result to
// combiner_output.rgb(), but instead store it in a temporary variable until
// alpha combining has been done.
Math::Vec3<u8> color_result[3] = {
Common::Vec3<u8> color_result[3] = {
GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)),
GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)),
GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)),
@ -631,10 +633,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// store the depth etc. Using float for now until we know more
// about Pica datatypes
if (regs.texturing.fog_mode == TexturingRegs::FogMode::Fog) {
const Math::Vec3<u8> fog_color = Math::MakeVec(regs.texturing.fog_color.r.Value(),
regs.texturing.fog_color.g.Value(),
regs.texturing.fog_color.b.Value())
.Cast<u8>();
const Common::Vec3<u8> fog_color =
Common::MakeVec(regs.texturing.fog_color.r.Value(),
regs.texturing.fog_color.g.Value(),
regs.texturing.fog_color.b.Value())
.Cast<u8>();
// Get index into fog LUT
float fog_index;
@ -778,7 +781,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
UpdateStencil(stencil_test.action_depth_pass);
auto dest = GetPixel(x >> 4, y >> 4);
Math::Vec4<u8> blend_output = combiner_output;
Common::Vec4<u8> blend_output = combiner_output;
if (output_merger.alphablend_enable) {
auto params = output_merger.alpha_blending;
@ -787,11 +790,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
FramebufferRegs::BlendFactor factor) -> u8 {
DEBUG_ASSERT(channel < 4);
const Math::Vec4<u8> blend_const =
Math::MakeVec(output_merger.blend_const.r.Value(),
output_merger.blend_const.g.Value(),
output_merger.blend_const.b.Value(),
output_merger.blend_const.a.Value())
const Common::Vec4<u8> blend_const =
Common::MakeVec(output_merger.blend_const.r.Value(),
output_merger.blend_const.g.Value(),
output_merger.blend_const.b.Value(),
output_merger.blend_const.a.Value())
.Cast<u8>();
switch (factor) {
@ -852,15 +855,15 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
return combiner_output[channel];
};
auto srcfactor = Math::MakeVec(LookupFactor(0, params.factor_source_rgb),
LookupFactor(1, params.factor_source_rgb),
LookupFactor(2, params.factor_source_rgb),
LookupFactor(3, params.factor_source_a));
auto srcfactor = Common::MakeVec(LookupFactor(0, params.factor_source_rgb),
LookupFactor(1, params.factor_source_rgb),
LookupFactor(2, params.factor_source_rgb),
LookupFactor(3, params.factor_source_a));
auto dstfactor = Math::MakeVec(LookupFactor(0, params.factor_dest_rgb),
LookupFactor(1, params.factor_dest_rgb),
LookupFactor(2, params.factor_dest_rgb),
LookupFactor(3, params.factor_dest_a));
auto dstfactor = Common::MakeVec(LookupFactor(0, params.factor_dest_rgb),
LookupFactor(1, params.factor_dest_rgb),
LookupFactor(2, params.factor_dest_rgb),
LookupFactor(3, params.factor_dest_a));
blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor,
params.blend_equation_rgb);
@ -869,13 +872,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
.a();
} else {
blend_output =
Math::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
Common::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
}
const Math::Vec4<u8> result = {
const Common::Vec4<u8> result = {
output_merger.red_enable ? blend_output.r() : dest.r(),
output_merger.green_enable ? blend_output.g() : dest.g(),
output_merger.blue_enable ? blend_output.b() : dest.b(),

View file

@ -13,7 +13,7 @@ struct Vertex : Shader::OutputVertex {
// Attributes used to store intermediate results
// position after perspective divide
Math::Vec3<float24> screenpos;
Common::Vec3<float24> screenpos;
// Linear interpolation
// factor: 0=this, 1=vtx

View file

@ -51,8 +51,8 @@ int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, uns
}
};
Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
const Math::Vec4<u8>& values) {
Common::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
const Common::Vec4<u8>& values) {
using ColorModifier = TevStageConfig::ColorModifier;
switch (factor) {
@ -60,37 +60,37 @@ Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
return values.rgb();
case ColorModifier::OneMinusSourceColor:
return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
case ColorModifier::SourceAlpha:
return values.aaa();
case ColorModifier::OneMinusSourceAlpha:
return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
case ColorModifier::SourceRed:
return values.rrr();
case ColorModifier::OneMinusSourceRed:
return (Math::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
case ColorModifier::SourceGreen:
return values.ggg();
case ColorModifier::OneMinusSourceGreen:
return (Math::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
case ColorModifier::SourceBlue:
return values.bbb();
case ColorModifier::OneMinusSourceBlue:
return (Math::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
}
UNREACHABLE();
};
u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>& values) {
u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Common::Vec4<u8>& values) {
using AlphaModifier = TevStageConfig::AlphaModifier;
switch (factor) {
@ -122,7 +122,7 @@ u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>&
UNREACHABLE();
};
Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> input[3]) {
Common::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Common::Vec3<u8> input[3]) {
using Operation = TevStageConfig::Operation;
switch (op) {
@ -144,7 +144,7 @@ Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> i
// TODO(bunnei): Verify that the color conversion from (float) 0.5f to
// (byte) 128 is correct
auto result =
input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128);
input[0].Cast<int>() + input[1].Cast<int>() - Common::MakeVec<int>(128, 128, 128);
result.r() = std::clamp<int>(result.r(), 0, 255);
result.g() = std::clamp<int>(result.g(), 0, 255);
result.b() = std::clamp<int>(result.b(), 0, 255);
@ -153,7 +153,7 @@ Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> i
case Operation::Lerp:
return ((input[0] * input[2] +
input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) /
input[1] * (Common::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) /
255)
.Cast<u8>();

View file

@ -12,14 +12,14 @@ namespace Pica::Rasterizer {
int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, unsigned size);
Math::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor,
const Math::Vec4<u8>& values);
Common::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor,
const Common::Vec4<u8>& values);
u8 GetAlphaModifier(TexturingRegs::TevStageConfig::AlphaModifier factor,
const Math::Vec4<u8>& values);
const Common::Vec4<u8>& values);
Math::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op,
const Math::Vec3<u8> input[3]);
Common::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op,
const Common::Vec3<u8> input[3]);
u8 AlphaCombine(TexturingRegs::TevStageConfig::Operation op, const std::array<u8, 3>& input);

View file

@ -69,14 +69,14 @@ union ETC1Tile {
BitField<60, 4, u64> r1;
} separate;
const Math::Vec3<u8> GetRGB(unsigned int x, unsigned int y) const {
const Common::Vec3<u8> GetRGB(unsigned int x, unsigned int y) const {
int texel = 4 * x + y;
if (flip)
std::swap(x, y);
// Lookup base value
Math::Vec3<int> ret;
Common::Vec3<int> ret;
if (differential_mode) {
ret.r() = static_cast<int>(differential.r);
ret.g() = static_cast<int>(differential.g);
@ -119,7 +119,7 @@ union ETC1Tile {
} // anonymous namespace
Math::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y) {
Common::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y) {
ETC1Tile tile{value};
return tile.GetRGB(x, y);
}

View file

@ -9,6 +9,6 @@
namespace Pica::Texture {
Math::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y);
Common::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y);
} // namespace Pica::Texture

View file

@ -56,8 +56,8 @@ size_t CalculateTileSize(TextureFormat format) {
}
}
Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
Common::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
// Coordinate in tiles
const unsigned int coarse_x = x / 8;
const unsigned int coarse_y = y / 8;
@ -71,8 +71,8 @@ Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
return LookupTexelInTile(tile, fine_x, fine_y, info, disable_alpha);
}
Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
Common::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
DEBUG_ASSERT(x < 8);
DEBUG_ASSERT(y < 8);
@ -200,8 +200,8 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int
u64_le subtile_data;
memcpy(&subtile_data, subtile_ptr, sizeof(u64));
return Math::MakeVec(SampleETC1Subtile(subtile_data, x, y),
disable_alpha ? (u8)255 : alpha);
return Common::MakeVec(SampleETC1Subtile(subtile_data, x, y),
disable_alpha ? (u8)255 : alpha);
}
default:

View file

@ -40,8 +40,8 @@ struct TextureInfo {
* channel.
* @todo Eventually we should get rid of the disable_alpha parameter.
*/
Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha = false);
Common::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha = false);
/**
* Looks up a texel from a single 8x8 texture tile.
@ -52,7 +52,7 @@ Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
* @param disable_alpha Used for debugging. Sets the result alpha to 255 and either discards the
* real alpha or inserts it in an otherwise unused channel.
*/
Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha);
Common::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha);
} // namespace Pica::Texture