renderer_opengl: Remove GLvec* types

* The common types already exist and provide all the functionality required, why invent new types?
master
emufan4568 2022-08-21 12:22:58 +07:00
parent e834f2b049
commit e6137d7874
6 changed files with 170 additions and 144 deletions

@ -31,6 +31,7 @@
#pragma once #pragma once
#include <cmath> #include <cmath>
#include <cstring>
#include <type_traits> #include <type_traits>
#include <boost/serialization/access.hpp> #include <boost/serialization/access.hpp>
@ -60,6 +61,10 @@ public:
return &x; return &x;
} }
const T* AsArray() const {
return &x;
}
constexpr Vec2() = default; constexpr Vec2() = default;
constexpr Vec2(const T& x_, const T& y_) : x(x_), y(y_) {} constexpr Vec2(const T& x_, const T& y_) : x(x_), y(y_) {}
@ -123,6 +128,14 @@ public:
return x * x + y * y; return x * x + y * y;
} }
[[nodiscard]] constexpr bool operator!=(const Vec2& other) const {
return std::memcmp(AsArray(), other.AsArray(), sizeof(Vec2)) != 0;
}
[[nodiscard]] constexpr bool operator==(const Vec2& other) const {
return std::memcmp(AsArray(), other.AsArray(), sizeof(Vec2)) == 0;
}
// Only implemented for T=float // Only implemented for T=float
[[nodiscard]] float Length() const; [[nodiscard]] float Length() const;
[[nodiscard]] float Normalize(); // returns the previous length, which is often useful [[nodiscard]] float Normalize(); // returns the previous length, which is often useful
@ -184,6 +197,8 @@ template <typename T, typename V>
} }
using Vec2f = Vec2<float>; using Vec2f = Vec2<float>;
using Vec2i = Vec2<int>;
using Vec2u = Vec2<unsigned int>;
template <> template <>
inline float Vec2<float>::Length() const { inline float Vec2<float>::Length() const {
@ -216,6 +231,10 @@ public:
return &x; return &x;
} }
const T* AsArray() const {
return &x;
}
constexpr Vec3() = default; constexpr Vec3() = default;
constexpr Vec3(const T& x_, const T& y_, const T& z_) : x(x_), y(y_), z(z_) {} constexpr Vec3(const T& x_, const T& y_, const T& z_) : x(x_), y(y_), z(z_) {}
@ -280,6 +299,14 @@ public:
return *this; return *this;
} }
[[nodiscard]] constexpr bool operator!=(const Vec3& other) const {
return std::memcmp(AsArray(), other.AsArray(), sizeof(Vec3)) != 0;
}
[[nodiscard]] constexpr bool operator==(const Vec3& other) const {
return std::memcmp(AsArray(), other.AsArray(), sizeof(Vec3)) == 0;
}
[[nodiscard]] constexpr T Length2() const { [[nodiscard]] constexpr T Length2() const {
return x * x + y * y + z * z; return x * x + y * y + z * z;
} }
@ -412,6 +439,8 @@ inline float Vec3<float>::Normalize() {
} }
using Vec3f = Vec3<float>; using Vec3f = Vec3<float>;
using Vec3i = Vec3<int>;
using Vec3u = Vec3<unsigned int>;
template <typename T> template <typename T>
class Vec4 { class Vec4 {
@ -434,6 +463,10 @@ public:
return &x; return &x;
} }
const T* AsArray() const {
return &x;
}
constexpr Vec4() = default; constexpr Vec4() = default;
constexpr Vec4(const T& x_, const T& y_, const T& z_, const T& w_) constexpr Vec4(const T& x_, const T& y_, const T& z_, const T& w_)
: x(x_), y(y_), z(z_), w(w_) {} : x(x_), y(y_), z(z_), w(w_) {}
@ -503,6 +536,14 @@ public:
return *this; return *this;
} }
[[nodiscard]] constexpr bool operator!=(const Vec4& other) const {
return std::memcmp(AsArray(), other.AsArray(), sizeof(Vec4)) != 0;
}
[[nodiscard]] constexpr bool operator==(const Vec4& other) const {
return std::memcmp(AsArray(), other.AsArray(), sizeof(Vec4)) == 0;
}
[[nodiscard]] constexpr T Length2() const { [[nodiscard]] constexpr T Length2() const {
return x * x + y * y + z * z + w * w; return x * x + y * y + z * z + w * w;
} }
@ -623,6 +664,8 @@ template <typename T, typename V>
} }
using Vec4f = Vec4<float>; using Vec4f = Vec4<float>;
using Vec4i = Vec4<int>;
using Vec4u = Vec4<unsigned int>;
template <typename T> template <typename T>
constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) {

@ -13,6 +13,7 @@
#include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_rasterizer.h"
#include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/gl_shader_gen.h"
#include "video_core/renderer_opengl/gl_vars.h" #include "video_core/renderer_opengl/gl_vars.h"
#include "video_core/renderer_opengl/pica_to_gl.h"
#include "video_core/renderer_opengl/renderer_opengl.h" #include "video_core/renderer_opengl/renderer_opengl.h"
#include "video_core/video_core.h" #include "video_core/video_core.h"
@ -1638,7 +1639,7 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(
if (border_color != config.border_color.raw) { if (border_color != config.border_color.raw) {
border_color = config.border_color.raw; border_color = config.border_color.raw;
auto gl_color = PicaToGL::ColorRGBA8(border_color); auto gl_color = PicaToGL::ColorRGBA8(border_color);
glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, gl_color.data()); glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, gl_color.AsArray());
} }
} }
@ -1668,7 +1669,7 @@ void RasterizerOpenGL::SyncClipEnabled() {
void RasterizerOpenGL::SyncClipCoef() { void RasterizerOpenGL::SyncClipCoef() {
const auto raw_clip_coef = Pica::g_state.regs.rasterizer.GetClipCoef(); const auto raw_clip_coef = Pica::g_state.regs.rasterizer.GetClipCoef();
const GLvec4 new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(), const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(),
raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()}; raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()};
if (new_clip_coef != uniform_block_data.data.clip_coef) { if (new_clip_coef != uniform_block_data.data.clip_coef) {
uniform_block_data.data.clip_coef = new_clip_coef; uniform_block_data.data.clip_coef = new_clip_coef;
@ -1939,10 +1940,12 @@ void RasterizerOpenGL::SyncLightAmbient(int light_index) {
} }
void RasterizerOpenGL::SyncLightPosition(int light_index) { void RasterizerOpenGL::SyncLightPosition(int light_index) {
GLvec3 position = { const auto& light = Pica::g_state.regs.lighting.light[light_index];
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(), const Common::Vec3f position = {
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(), Pica::float16::FromRaw(light.x).ToFloat32(),
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()}; Pica::float16::FromRaw(light.y).ToFloat32(),
Pica::float16::FromRaw(light.z).ToFloat32()
};
if (position != uniform_block_data.data.light_src[light_index].position) { if (position != uniform_block_data.data.light_src[light_index].position) {
uniform_block_data.data.light_src[light_index].position = position; uniform_block_data.data.light_src[light_index].position = position;
@ -1952,8 +1955,8 @@ void RasterizerOpenGL::SyncLightPosition(int light_index) {
void RasterizerOpenGL::SyncLightSpotDirection(int light_index) { void RasterizerOpenGL::SyncLightSpotDirection(int light_index) {
const auto& light = Pica::g_state.regs.lighting.light[light_index]; const auto& light = Pica::g_state.regs.lighting.light[light_index];
GLvec3 spot_direction = {light.spot_x / 2047.0f, light.spot_y / 2047.0f, const auto spot_direction = Common::Vec3u{light.spot_x, light.spot_y, light.spot_z}
light.spot_z / 2047.0f}; / 2047.0f;
if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) { if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) {
uniform_block_data.data.light_src[light_index].spot_direction = spot_direction; uniform_block_data.data.light_src[light_index].spot_direction = spot_direction;
@ -1962,9 +1965,8 @@ void RasterizerOpenGL::SyncLightSpotDirection(int light_index) {
} }
void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) { void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) {
GLfloat dist_atten_bias = const auto& light = Pica::g_state.regs.lighting.light[light_index];
Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias) float dist_atten_bias = Pica::float20::FromRaw(light.dist_atten_bias).ToFloat32();
.ToFloat32();
if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) {
uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias;
@ -1973,9 +1975,8 @@ void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) {
} }
void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) { void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) {
GLfloat dist_atten_scale = const auto& light = Pica::g_state.regs.lighting.light[light_index];
Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale) float dist_atten_scale = Pica::float20::FromRaw(light.dist_atten_scale).ToFloat32();
.ToFloat32();
if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) {
uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale;
@ -2006,7 +2007,8 @@ void RasterizerOpenGL::SyncShadowTextureBias() {
void RasterizerOpenGL::SyncAndUploadLUTsLF() { void RasterizerOpenGL::SyncAndUploadLUTsLF() {
constexpr std::size_t max_size = constexpr std::size_t max_size =
sizeof(GLvec2) * 256 * Pica::LightingRegs::NumLightingSampler + sizeof(GLvec2) * 128; // fog sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler +
sizeof(Common::Vec2f) * 128; // fog
if (!uniform_block_data.lighting_lut_dirty_any && !uniform_block_data.fog_lut_dirty) { if (!uniform_block_data.lighting_lut_dirty_any && !uniform_block_data.fog_lut_dirty) {
return; return;
@ -2017,27 +2019,27 @@ void RasterizerOpenGL::SyncAndUploadLUTsLF() {
bool invalidate; bool invalidate;
std::size_t bytes_used = 0; std::size_t bytes_used = 0;
glBindBuffer(GL_TEXTURE_BUFFER, texture_lf_buffer.GetHandle()); glBindBuffer(GL_TEXTURE_BUFFER, texture_lf_buffer.GetHandle());
std::tie(buffer, offset, invalidate) = texture_lf_buffer.Map(max_size, sizeof(GLvec4)); std::tie(buffer, offset, invalidate) = texture_lf_buffer.Map(max_size, sizeof(Common::Vec4f));
// Sync the lighting luts // Sync the lighting luts
if (uniform_block_data.lighting_lut_dirty_any || invalidate) { if (uniform_block_data.lighting_lut_dirty_any || invalidate) {
for (unsigned index = 0; index < uniform_block_data.lighting_lut_dirty.size(); index++) { for (unsigned index = 0; index < uniform_block_data.lighting_lut_dirty.size(); index++) {
if (uniform_block_data.lighting_lut_dirty[index] || invalidate) { if (uniform_block_data.lighting_lut_dirty[index] || invalidate) {
std::array<GLvec2, 256> new_data; std::array<Common::Vec2f, 256> new_data;
const auto& source_lut = Pica::g_state.lighting.luts[index]; const auto& source_lut = Pica::g_state.lighting.luts[index];
std::transform(source_lut.begin(), source_lut.end(), new_data.begin(), std::transform(source_lut.begin(), source_lut.end(), new_data.begin(),
[](const auto& entry) { [](const auto& entry) {
return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()};
}); });
if (new_data != lighting_lut_data[index] || invalidate) { if (new_data != lighting_lut_data[index] || invalidate) {
lighting_lut_data[index] = new_data; lighting_lut_data[index] = new_data;
std::memcpy(buffer + bytes_used, new_data.data(), std::memcpy(buffer + bytes_used, new_data.data(),
new_data.size() * sizeof(GLvec2)); new_data.size() * sizeof(Common::Vec2f));
uniform_block_data.data.lighting_lut_offset[index / 4][index % 4] = uniform_block_data.data.lighting_lut_offset[index / 4][index % 4] =
static_cast<GLint>((offset + bytes_used) / sizeof(GLvec2)); static_cast<GLint>((offset + bytes_used) / sizeof(Common::Vec2f));
uniform_block_data.dirty = true; uniform_block_data.dirty = true;
bytes_used += new_data.size() * sizeof(GLvec2); bytes_used += new_data.size() * sizeof(Common::Vec2f);
} }
uniform_block_data.lighting_lut_dirty[index] = false; uniform_block_data.lighting_lut_dirty[index] = false;
} }
@ -2047,20 +2049,20 @@ void RasterizerOpenGL::SyncAndUploadLUTsLF() {
// Sync the fog lut // Sync the fog lut
if (uniform_block_data.fog_lut_dirty || invalidate) { if (uniform_block_data.fog_lut_dirty || invalidate) {
std::array<GLvec2, 128> new_data; std::array<Common::Vec2f, 128> new_data;
std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(),
[](const auto& entry) { [](const auto& entry) {
return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()};
}); });
if (new_data != fog_lut_data || invalidate) { if (new_data != fog_lut_data || invalidate) {
fog_lut_data = new_data; fog_lut_data = new_data;
std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(GLvec2)); std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(Common::Vec2f));
uniform_block_data.data.fog_lut_offset = uniform_block_data.data.fog_lut_offset =
static_cast<GLint>((offset + bytes_used) / sizeof(GLvec2)); static_cast<int>((offset + bytes_used) / sizeof(Common::Vec2f));
uniform_block_data.dirty = true; uniform_block_data.dirty = true;
bytes_used += new_data.size() * sizeof(GLvec2); bytes_used += new_data.size() * sizeof(Common::Vec2f);
} }
uniform_block_data.fog_lut_dirty = false; uniform_block_data.fog_lut_dirty = false;
} }
@ -2069,9 +2071,9 @@ void RasterizerOpenGL::SyncAndUploadLUTsLF() {
} }
void RasterizerOpenGL::SyncAndUploadLUTs() { void RasterizerOpenGL::SyncAndUploadLUTs() {
constexpr std::size_t max_size = sizeof(GLvec2) * 128 * 3 + // proctex: noise + color + alpha constexpr std::size_t max_size = sizeof(Common::Vec2f) * 128 * 3 + // proctex: noise + color + alpha
sizeof(GLvec4) * 256 + // proctex sizeof(Common::Vec4f) * 256 + // proctex
sizeof(GLvec4) * 256; // proctex diff sizeof(Common::Vec4f) * 256; // proctex diff
if (!uniform_block_data.proctex_noise_lut_dirty && if (!uniform_block_data.proctex_noise_lut_dirty &&
!uniform_block_data.proctex_color_map_dirty && !uniform_block_data.proctex_color_map_dirty &&
@ -2085,23 +2087,23 @@ void RasterizerOpenGL::SyncAndUploadLUTs() {
bool invalidate; bool invalidate;
std::size_t bytes_used = 0; std::size_t bytes_used = 0;
glBindBuffer(GL_TEXTURE_BUFFER, texture_buffer.GetHandle()); glBindBuffer(GL_TEXTURE_BUFFER, texture_buffer.GetHandle());
std::tie(buffer, offset, invalidate) = texture_buffer.Map(max_size, sizeof(GLvec4)); std::tie(buffer, offset, invalidate) = texture_buffer.Map(max_size, sizeof(Common::Vec4f));
// helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap // helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap
auto SyncProcTexValueLUT = [this, buffer, offset, invalidate, &bytes_used]( auto SyncProcTexValueLUT = [this, buffer, offset, invalidate, &bytes_used](
const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut, const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut,
std::array<GLvec2, 128>& lut_data, GLint& lut_offset) { std::array<Common::Vec2f, 128>& lut_data, GLint& lut_offset) {
std::array<GLvec2, 128> new_data; std::array<Common::Vec2f, 128> new_data;
std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) {
return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()};
}); });
if (new_data != lut_data || invalidate) { if (new_data != lut_data || invalidate) {
lut_data = new_data; lut_data = new_data;
std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(GLvec2)); std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(Common::Vec2f));
lut_offset = static_cast<GLint>((offset + bytes_used) / sizeof(GLvec2)); lut_offset = static_cast<GLint>((offset + bytes_used) / sizeof(Common::Vec2f));
uniform_block_data.dirty = true; uniform_block_data.dirty = true;
bytes_used += new_data.size() * sizeof(GLvec2); bytes_used += new_data.size() * sizeof(Common::Vec2f);
} }
}; };
@ -2128,44 +2130,44 @@ void RasterizerOpenGL::SyncAndUploadLUTs() {
// Sync the proctex lut // Sync the proctex lut
if (uniform_block_data.proctex_lut_dirty || invalidate) { if (uniform_block_data.proctex_lut_dirty || invalidate) {
std::array<GLvec4, 256> new_data; std::array<Common::Vec4f, 256> new_data;
std::transform(Pica::g_state.proctex.color_table.begin(), std::transform(Pica::g_state.proctex.color_table.begin(),
Pica::g_state.proctex.color_table.end(), new_data.begin(), Pica::g_state.proctex.color_table.end(), new_data.begin(),
[](const auto& entry) { [](const auto& entry) {
auto rgba = entry.ToVector() / 255.0f; auto rgba = entry.ToVector() / 255.0f;
return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()}; return Common::Vec4f{rgba.r(), rgba.g(), rgba.b(), rgba.a()};
}); });
if (new_data != proctex_lut_data || invalidate) { if (new_data != proctex_lut_data || invalidate) {
proctex_lut_data = new_data; proctex_lut_data = new_data;
std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(GLvec4)); std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(Common::Vec4f));
uniform_block_data.data.proctex_lut_offset = uniform_block_data.data.proctex_lut_offset =
static_cast<GLint>((offset + bytes_used) / sizeof(GLvec4)); static_cast<GLint>((offset + bytes_used) / sizeof(Common::Vec4f));
uniform_block_data.dirty = true; uniform_block_data.dirty = true;
bytes_used += new_data.size() * sizeof(GLvec4); bytes_used += new_data.size() * sizeof(Common::Vec4f);
} }
uniform_block_data.proctex_lut_dirty = false; uniform_block_data.proctex_lut_dirty = false;
} }
// Sync the proctex difference lut // Sync the proctex difference lut
if (uniform_block_data.proctex_diff_lut_dirty || invalidate) { if (uniform_block_data.proctex_diff_lut_dirty || invalidate) {
std::array<GLvec4, 256> new_data; std::array<Common::Vec4f, 256> new_data;
std::transform(Pica::g_state.proctex.color_diff_table.begin(), std::transform(Pica::g_state.proctex.color_diff_table.begin(),
Pica::g_state.proctex.color_diff_table.end(), new_data.begin(), Pica::g_state.proctex.color_diff_table.end(), new_data.begin(),
[](const auto& entry) { [](const auto& entry) {
auto rgba = entry.ToVector() / 255.0f; auto rgba = entry.ToVector() / 255.0f;
return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()}; return Common::Vec4f{rgba.r(), rgba.g(), rgba.b(), rgba.a()};
}); });
if (new_data != proctex_diff_lut_data || invalidate) { if (new_data != proctex_diff_lut_data || invalidate) {
proctex_diff_lut_data = new_data; proctex_diff_lut_data = new_data;
std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(GLvec4)); std::memcpy(buffer + bytes_used, new_data.data(), new_data.size() * sizeof(Common::Vec4f));
uniform_block_data.data.proctex_diff_lut_offset = uniform_block_data.data.proctex_diff_lut_offset =
static_cast<GLint>((offset + bytes_used) / sizeof(GLvec4)); static_cast<GLint>((offset + bytes_used) / sizeof(Common::Vec4f));
uniform_block_data.dirty = true; uniform_block_data.dirty = true;
bytes_used += new_data.size() * sizeof(GLvec4); bytes_used += new_data.size() * sizeof(Common::Vec4f);
} }
uniform_block_data.proctex_diff_lut_dirty = false; uniform_block_data.proctex_diff_lut_dirty = false;
} }

@ -13,7 +13,6 @@
#include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_shader_manager.h"
#include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_state.h"
#include "video_core/renderer_opengl/gl_stream_buffer.h" #include "video_core/renderer_opengl/gl_stream_buffer.h"
#include "video_core/renderer_opengl/pica_to_gl.h"
#include "video_core/shader/shader.h" #include "video_core/shader/shader.h"
namespace Frontend { namespace Frontend {
@ -105,20 +104,18 @@ private:
view[2] = v.view.z.ToFloat32(); view[2] = v.view.z.ToFloat32();
if (flip_quaternion) { if (flip_quaternion) {
for (float& x : normquat) { normquat = -normquat;
x = -x;
}
} }
} }
GLvec4 position; Common::Vec4f position;
GLvec4 color; Common::Vec4f color;
GLvec2 tex_coord0; Common::Vec2f tex_coord0;
GLvec2 tex_coord1; Common::Vec2f tex_coord1;
GLvec2 tex_coord2; Common::Vec2f tex_coord2;
GLfloat tex_coord0_w; float tex_coord0_w;
GLvec4 normquat; Common::Vec4f normquat;
GLvec3 view; Common::Vec3f view;
}; };
/// Syncs the clip enabled status to match the PICA register /// Syncs the clip enabled status to match the PICA register
@ -301,13 +298,13 @@ private:
OGLTexture texture_buffer_lut_rg; OGLTexture texture_buffer_lut_rg;
OGLTexture texture_buffer_lut_rgba; OGLTexture texture_buffer_lut_rgba;
std::array<std::array<GLvec2, 256>, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{}; std::array<std::array<Common::Vec2f, 256>, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{};
std::array<GLvec2, 128> fog_lut_data{}; std::array<Common::Vec2f, 128> fog_lut_data{};
std::array<GLvec2, 128> proctex_noise_lut_data{}; std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
std::array<GLvec2, 128> proctex_color_map_data{}; std::array<Common::Vec2f, 128> proctex_color_map_data{};
std::array<GLvec2, 128> proctex_alpha_map_data{}; std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
std::array<GLvec4, 256> proctex_lut_data{}; std::array<Common::Vec4f, 256> proctex_lut_data{};
std::array<GLvec4, 256> proctex_diff_lut_data{}; std::array<Common::Vec4f, 256> proctex_diff_lut_data{};
}; };
} // namespace OpenGL } // namespace OpenGL

@ -4,6 +4,7 @@
#include <algorithm> #include <algorithm>
#include <thread> #include <thread>
#include <set>
#include <unordered_map> #include <unordered_map>
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
@ -150,11 +151,11 @@ void PicaUniformsData::SetFromRegs(const Pica::ShaderRegs& regs,
std::transform(std::begin(setup.uniforms.b), std::end(setup.uniforms.b), std::begin(bools), std::transform(std::begin(setup.uniforms.b), std::end(setup.uniforms.b), std::begin(bools),
[](bool value) -> BoolAligned { return {value ? GL_TRUE : GL_FALSE}; }); [](bool value) -> BoolAligned { return {value ? GL_TRUE : GL_FALSE}; });
std::transform(std::begin(regs.int_uniforms), std::end(regs.int_uniforms), std::begin(i), std::transform(std::begin(regs.int_uniforms), std::end(regs.int_uniforms), std::begin(i),
[](const auto& value) -> GLuvec4 { [](const auto& value) -> Common::Vec4u {
return {value.x.Value(), value.y.Value(), value.z.Value(), value.w.Value()}; return {value.x.Value(), value.y.Value(), value.z.Value(), value.w.Value()};
}); });
std::transform(std::begin(setup.uniforms.f), std::end(setup.uniforms.f), std::begin(f), std::transform(std::begin(setup.uniforms.f), std::end(setup.uniforms.f), std::begin(f),
[](const auto& value) -> GLvec4 { [](const auto& value) -> Common::Vec4f {
return {value.x.ToFloat32(), value.y.ToFloat32(), value.z.ToFloat32(), return {value.x.ToFloat32(), value.y.ToFloat32(), value.z.ToFloat32(),
value.w.ToFloat32()}; value.w.ToFloat32()};
}); });

@ -5,34 +5,40 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "common/vector_math.h"
#include "video_core/rasterizer_interface.h" #include "video_core/rasterizer_interface.h"
#include "video_core/renderer_opengl/pica_to_gl.h" #include "video_core/regs_lighting.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Frontend {
class EmuWindow;
}
namespace Pica { namespace Pica {
struct Regs; struct Regs;
struct ShaderRegs; struct ShaderRegs;
namespace Shader {
struct ShaderSetup;
} }
namespace Pica::Shader {
struct ShaderSetup;
} }
namespace OpenGL { namespace OpenGL {
enum class UniformBindings : GLuint { Common, VS, GS }; enum class UniformBindings : u32 { Common, VS, GS };
struct LightSrc { struct LightSrc {
alignas(16) GLvec3 specular_0; alignas(16) Common::Vec3f specular_0;
alignas(16) GLvec3 specular_1; alignas(16) Common::Vec3f specular_1;
alignas(16) GLvec3 diffuse; alignas(16) Common::Vec3f diffuse;
alignas(16) GLvec3 ambient; alignas(16) Common::Vec3f ambient;
alignas(16) GLvec3 position; alignas(16) Common::Vec3f position;
alignas(16) GLvec3 spot_direction; // negated alignas(16) Common::Vec3f spot_direction; // negated
GLfloat dist_atten_bias; float dist_atten_bias;
GLfloat dist_atten_scale; float dist_atten_scale;
}; };
/// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned
@ -40,39 +46,38 @@ struct LightSrc {
// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
// Not following that rule will cause problems on some AMD drivers. // Not following that rule will cause problems on some AMD drivers.
struct UniformData { struct UniformData {
GLint framebuffer_scale; int framebuffer_scale;
GLint alphatest_ref; int alphatest_ref;
GLfloat depth_scale; float depth_scale;
GLfloat depth_offset; float depth_offset;
GLfloat shadow_bias_constant; float shadow_bias_constant;
GLfloat shadow_bias_linear; float shadow_bias_linear;
GLint scissor_x1; int scissor_x1;
GLint scissor_y1; int scissor_y1;
GLint scissor_x2; int scissor_x2;
GLint scissor_y2; int scissor_y2;
GLint fog_lut_offset; int fog_lut_offset;
GLint proctex_noise_lut_offset; int proctex_noise_lut_offset;
GLint proctex_color_map_offset; int proctex_color_map_offset;
GLint proctex_alpha_map_offset; int proctex_alpha_map_offset;
GLint proctex_lut_offset; int proctex_lut_offset;
GLint proctex_diff_lut_offset; int proctex_diff_lut_offset;
GLfloat proctex_bias; float proctex_bias;
GLint shadow_texture_bias; int shadow_texture_bias;
alignas(16) GLivec4 lighting_lut_offset[Pica::LightingRegs::NumLightingSampler / 4]; alignas(16) Common::Vec4i lighting_lut_offset[Pica::LightingRegs::NumLightingSampler / 4];
alignas(16) GLvec3 fog_color; alignas(16) Common::Vec3f fog_color;
alignas(8) GLvec2 proctex_noise_f; alignas(8) Common::Vec2f proctex_noise_f;
alignas(8) GLvec2 proctex_noise_a; alignas(8) Common::Vec2f proctex_noise_a;
alignas(8) GLvec2 proctex_noise_p; alignas(8) Common::Vec2f proctex_noise_p;
alignas(16) GLvec3 lighting_global_ambient; alignas(16) Common::Vec3f lighting_global_ambient;
LightSrc light_src[8]; LightSrc light_src[8];
alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages alignas(16) Common::Vec4f const_color[6]; // A vec4 color for each of the six tev stages
alignas(16) GLvec4 tev_combiner_buffer_color; alignas(16) Common::Vec4f tev_combiner_buffer_color;
alignas(16) GLvec4 clip_coef; alignas(16) Common::Vec4f clip_coef;
}; };
static_assert( static_assert(sizeof(UniformData) == 0x4F0,
sizeof(UniformData) == 0x4F0, "The size of the UniformData does not match the structure in the shader");
"The size of the UniformData structure has changed, update the structure in the shader");
static_assert(sizeof(UniformData) < 16384, static_assert(sizeof(UniformData) < 16384,
"UniformData structure must be less than 16kb as per the OpenGL spec"); "UniformData structure must be less than 16kb as per the OpenGL spec");
@ -82,20 +87,19 @@ struct PicaUniformsData {
void SetFromRegs(const Pica::ShaderRegs& regs, const Pica::Shader::ShaderSetup& setup); void SetFromRegs(const Pica::ShaderRegs& regs, const Pica::Shader::ShaderSetup& setup);
struct BoolAligned { struct BoolAligned {
alignas(16) GLint b; alignas(16) int b;
}; };
std::array<BoolAligned, 16> bools; std::array<BoolAligned, 16> bools;
alignas(16) std::array<GLuvec4, 4> i; alignas(16) std::array<Common::Vec4u, 4> i;
alignas(16) std::array<GLvec4, 96> f; alignas(16) std::array<Common::Vec4f, 96> f;
}; };
struct VSUniformData { struct VSUniformData {
PicaUniformsData uniforms; PicaUniformsData uniforms;
}; };
static_assert( static_assert(sizeof(VSUniformData) == 1856,
sizeof(VSUniformData) == 1856, "The size of the VSUniformData does not match the structure in the shader");
"The size of the VSUniformData structure has changed, update the structure in the shader");
static_assert(sizeof(VSUniformData) < 16384, static_assert(sizeof(VSUniformData) < 16384,
"VSUniformData structure must be less than 16kb as per the OpenGL spec"); "VSUniformData structure must be less than 16kb as per the OpenGL spec");

@ -1,32 +1,18 @@
// Copyright 2015 Citra Emulator Project // Copyright 2022 Citra Emulator Project
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#pragma once #pragma once
#include <array> #include <array>
#include <cstddef>
#include <glad/glad.h> #include <glad/glad.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "video_core/regs_framebuffer.h" #include "video_core/regs_framebuffer.h"
#include "video_core/regs_lighting.h" #include "video_core/regs_lighting.h"
#include "video_core/regs_texturing.h" #include "video_core/regs_texturing.h"
using GLvec2 = std::array<GLfloat, 2>;
using GLvec3 = std::array<GLfloat, 3>;
using GLvec4 = std::array<GLfloat, 4>;
using GLuvec2 = std::array<GLuint, 2>;
using GLuvec3 = std::array<GLuint, 3>;
using GLuvec4 = std::array<GLuint, 4>;
using GLivec2 = std::array<GLint, 2>;
using GLivec3 = std::array<GLint, 3>;
using GLivec4 = std::array<GLint, 4>;
namespace PicaToGL { namespace PicaToGL {
using TextureFilter = Pica::TexturingRegs::TextureConfig::TextureFilter; using TextureFilter = Pica::TexturingRegs::TextureConfig::TextureFilter;
@ -245,21 +231,14 @@ inline GLenum StencilOp(Pica::FramebufferRegs::StencilAction action) {
return stencil_op_table[index]; return stencil_op_table[index];
} }
inline GLvec4 ColorRGBA8(const u32 color) { inline Common::Vec4f ColorRGBA8(const u32 color) {
return {{ const auto rgba = Common::Vec4u{color >> 0 & 0xFF, color >> 8 & 0xFF,
(color >> 0 & 0xFF) / 255.0f, color >> 16 & 0xFF, color >> 24 & 0xFF};
(color >> 8 & 0xFF) / 255.0f, return rgba / 255.0f;
(color >> 16 & 0xFF) / 255.0f,
(color >> 24 & 0xFF) / 255.0f,
}};
} }
inline std::array<GLfloat, 3> LightColor(const Pica::LightingRegs::LightColor& color) { inline Common::Vec3f LightColor(const Pica::LightingRegs::LightColor& color) {
return {{ return Common::Vec3u{color.r, color.g, color.b} / 255.0f;
color.r / 255.0f,
color.g / 255.0f,
color.b / 255.0f,
}};
} }
} // namespace PicaToGL } // namespace PicaToGL