renderer_opengl: Remove GLvec* types
* The common types already exist and provide all the functionality required, why invent new types?
This commit is contained in:
parent
e834f2b049
commit
e6137d7874
|
@ -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,8 +1669,8 @@ 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;
|
||||||
uniform_block_data.dirty = true;
|
uniform_block_data.dirty = true;
|
||||||
|
@ -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
|
||||||
|
|
Reference in New Issue