video_core: Move api agnostic uniform updates to RasterizerAccelerated
This commit is contained in:
@ -5,10 +5,25 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "video_core/rasterizer_accelerated.h"
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
|
#include "video_core/pica_state.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
|
static Common::Vec4f ColorRGBA8(const u32 color) {
|
||||||
|
const auto rgba =
|
||||||
|
Common::Vec4u{color >> 0 & 0xFF, color >> 8 & 0xFF, color >> 16 & 0xFF, color >> 24 & 0xFF};
|
||||||
|
return rgba / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Common::Vec3f LightColor(const Pica::LightingRegs::LightColor& color) {
|
||||||
|
return Common::Vec3u{color.r, color.g, color.b} / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
RasterizerAccelerated::RasterizerAccelerated() {
|
||||||
|
uniform_block_data.lighting_lut_dirty.fill(true);
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerAccelerated::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) {
|
void RasterizerAccelerated::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) {
|
||||||
const u32 page_start = addr >> Memory::CITRA_PAGE_BITS;
|
const u32 page_start = addr >> Memory::CITRA_PAGE_BITS;
|
||||||
const u32 page_end = ((addr + size - 1) >> Memory::CITRA_PAGE_BITS) + 1;
|
const u32 page_end = ((addr + size - 1) >> Memory::CITRA_PAGE_BITS) + 1;
|
||||||
@ -101,4 +116,195 @@ void RasterizerAccelerated::ClearAll(bool flush) {
|
|||||||
cached_pages = {};
|
cached_pages = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncDepthScale() {
|
||||||
|
float depth_scale =
|
||||||
|
Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32();
|
||||||
|
|
||||||
|
if (depth_scale != uniform_block_data.data.depth_scale) {
|
||||||
|
uniform_block_data.data.depth_scale = depth_scale;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncDepthOffset() {
|
||||||
|
float depth_offset =
|
||||||
|
Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32();
|
||||||
|
|
||||||
|
if (depth_offset != uniform_block_data.data.depth_offset) {
|
||||||
|
uniform_block_data.data.depth_offset = depth_offset;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncFogColor() {
|
||||||
|
const auto& regs = Pica::g_state.regs;
|
||||||
|
uniform_block_data.data.fog_color = {
|
||||||
|
regs.texturing.fog_color.r.Value() / 255.0f,
|
||||||
|
regs.texturing.fog_color.g.Value() / 255.0f,
|
||||||
|
regs.texturing.fog_color.b.Value() / 255.0f,
|
||||||
|
};
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncProcTexNoise() {
|
||||||
|
const auto& regs = Pica::g_state.regs.texturing;
|
||||||
|
uniform_block_data.data.proctex_noise_f = {
|
||||||
|
Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(),
|
||||||
|
Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(),
|
||||||
|
};
|
||||||
|
uniform_block_data.data.proctex_noise_a = {
|
||||||
|
regs.proctex_noise_u.amplitude / 4095.0f,
|
||||||
|
regs.proctex_noise_v.amplitude / 4095.0f,
|
||||||
|
};
|
||||||
|
uniform_block_data.data.proctex_noise_p = {
|
||||||
|
Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(),
|
||||||
|
Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(),
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncProcTexBias() {
|
||||||
|
const auto& regs = Pica::g_state.regs.texturing;
|
||||||
|
uniform_block_data.data.proctex_bias =
|
||||||
|
Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8))
|
||||||
|
.ToFloat32();
|
||||||
|
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncAlphaTest() {
|
||||||
|
const auto& regs = Pica::g_state.regs;
|
||||||
|
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
||||||
|
uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncCombinerColor() {
|
||||||
|
auto combiner_color =
|
||||||
|
ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw);
|
||||||
|
if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) {
|
||||||
|
uniform_block_data.data.tev_combiner_buffer_color = combiner_color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncTevConstColor(std::size_t stage_index,
|
||||||
|
const Pica::TexturingRegs::TevStageConfig& tev_stage) {
|
||||||
|
const auto const_color = ColorRGBA8(tev_stage.const_color);
|
||||||
|
|
||||||
|
if (const_color == uniform_block_data.data.const_color[stage_index]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform_block_data.data.const_color[stage_index] = const_color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncGlobalAmbient() {
|
||||||
|
auto color = LightColor(Pica::g_state.regs.lighting.global_ambient);
|
||||||
|
if (color != uniform_block_data.data.lighting_global_ambient) {
|
||||||
|
uniform_block_data.data.lighting_global_ambient = color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightSpecular0(int light_index) {
|
||||||
|
auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0);
|
||||||
|
if (color != uniform_block_data.data.light_src[light_index].specular_0) {
|
||||||
|
uniform_block_data.data.light_src[light_index].specular_0 = color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightSpecular1(int light_index) {
|
||||||
|
auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1);
|
||||||
|
if (color != uniform_block_data.data.light_src[light_index].specular_1) {
|
||||||
|
uniform_block_data.data.light_src[light_index].specular_1 = color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightDiffuse(int light_index) {
|
||||||
|
auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
|
||||||
|
if (color != uniform_block_data.data.light_src[light_index].diffuse) {
|
||||||
|
uniform_block_data.data.light_src[light_index].diffuse = color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightAmbient(int light_index) {
|
||||||
|
auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].ambient);
|
||||||
|
if (color != uniform_block_data.data.light_src[light_index].ambient) {
|
||||||
|
uniform_block_data.data.light_src[light_index].ambient = color;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightPosition(int light_index) {
|
||||||
|
const Common::Vec3f position = {
|
||||||
|
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(),
|
||||||
|
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(),
|
||||||
|
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()};
|
||||||
|
|
||||||
|
if (position != uniform_block_data.data.light_src[light_index].position) {
|
||||||
|
uniform_block_data.data.light_src[light_index].position = position;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightSpotDirection(int light_index) {
|
||||||
|
const auto& light = Pica::g_state.regs.lighting.light[light_index];
|
||||||
|
const auto spot_direction = Common::Vec3f{light.spot_x / 2047.0f, light.spot_y / 2047.0f, light.spot_z / 2047.0f};
|
||||||
|
|
||||||
|
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.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightDistanceAttenuationBias(int light_index) {
|
||||||
|
float dist_atten_bias =
|
||||||
|
Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias)
|
||||||
|
.ToFloat32();
|
||||||
|
|
||||||
|
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.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncLightDistanceAttenuationScale(int light_index) {
|
||||||
|
float dist_atten_scale =
|
||||||
|
Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale)
|
||||||
|
.ToFloat32();
|
||||||
|
|
||||||
|
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.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncShadowBias() {
|
||||||
|
const auto& shadow = Pica::g_state.regs.framebuffer.shadow;
|
||||||
|
float constant = Pica::float16::FromRaw(shadow.constant).ToFloat32();
|
||||||
|
float linear = Pica::float16::FromRaw(shadow.linear).ToFloat32();
|
||||||
|
|
||||||
|
if (constant != uniform_block_data.data.shadow_bias_constant ||
|
||||||
|
linear != uniform_block_data.data.shadow_bias_linear) {
|
||||||
|
uniform_block_data.data.shadow_bias_constant = constant;
|
||||||
|
uniform_block_data.data.shadow_bias_linear = linear;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerAccelerated::SyncShadowTextureBias() {
|
||||||
|
int bias = Pica::g_state.regs.texturing.shadow.bias << 1;
|
||||||
|
if (bias != uniform_block_data.data.shadow_texture_bias) {
|
||||||
|
uniform_block_data.data.shadow_texture_bias = bias;
|
||||||
|
uniform_block_data.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
@ -3,19 +3,107 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/vector_math.h"
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_interface.h"
|
||||||
|
#include "video_core/regs_texturing.h"
|
||||||
|
#include "video_core/shader/shader_uniforms.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
class RasterizerAccelerated : public RasterizerInterface {
|
class RasterizerAccelerated : public RasterizerInterface {
|
||||||
public:
|
public:
|
||||||
|
RasterizerAccelerated();
|
||||||
virtual ~RasterizerAccelerated() = default;
|
virtual ~RasterizerAccelerated() = default;
|
||||||
|
|
||||||
void UpdatePagesCachedCount(PAddr addr, u32 size, int delta) override;
|
void UpdatePagesCachedCount(PAddr addr, u32 size, int delta) override;
|
||||||
|
|
||||||
void ClearAll(bool flush) override;
|
void ClearAll(bool flush) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Syncs the depth scale to match the PICA register
|
||||||
|
void SyncDepthScale();
|
||||||
|
|
||||||
|
/// Syncs the depth offset to match the PICA register
|
||||||
|
void SyncDepthOffset();
|
||||||
|
|
||||||
|
/// Syncs the fog states to match the PICA register
|
||||||
|
void SyncFogColor();
|
||||||
|
|
||||||
|
/// Sync the procedural texture noise configuration to match the PICA register
|
||||||
|
void SyncProcTexNoise();
|
||||||
|
|
||||||
|
/// Sync the procedural texture bias configuration to match the PICA register
|
||||||
|
void SyncProcTexBias();
|
||||||
|
|
||||||
|
/// Syncs the alpha test states to match the PICA register
|
||||||
|
void SyncAlphaTest();
|
||||||
|
|
||||||
|
/// Syncs the TEV combiner color buffer to match the PICA register
|
||||||
|
void SyncCombinerColor();
|
||||||
|
|
||||||
|
/// Syncs the TEV constant color to match the PICA register
|
||||||
|
void SyncTevConstColor(std::size_t tev_index,
|
||||||
|
const Pica::TexturingRegs::TevStageConfig& tev_stage);
|
||||||
|
|
||||||
|
/// Syncs the lighting global ambient color to match the PICA register
|
||||||
|
void SyncGlobalAmbient();
|
||||||
|
|
||||||
|
/// Syncs the specified light's specular 0 color to match the PICA register
|
||||||
|
void SyncLightSpecular0(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified light's specular 1 color to match the PICA register
|
||||||
|
void SyncLightSpecular1(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified light's diffuse color to match the PICA register
|
||||||
|
void SyncLightDiffuse(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified light's ambient color to match the PICA register
|
||||||
|
void SyncLightAmbient(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified light's position to match the PICA register
|
||||||
|
void SyncLightPosition(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified spot light direcition to match the PICA register
|
||||||
|
void SyncLightSpotDirection(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified light's distance attenuation bias to match the PICA register
|
||||||
|
void SyncLightDistanceAttenuationBias(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the specified light's distance attenuation scale to match the PICA register
|
||||||
|
void SyncLightDistanceAttenuationScale(int light_index);
|
||||||
|
|
||||||
|
/// Syncs the shadow rendering bias to match the PICA register
|
||||||
|
void SyncShadowBias();
|
||||||
|
|
||||||
|
/// Syncs the shadow texture bias to match the PICA register
|
||||||
|
void SyncShadowTextureBias();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct UniformBlockData {
|
||||||
|
Pica::Shader::UniformData data{};
|
||||||
|
std::array<bool, Pica::LightingRegs::NumLightingSampler> lighting_lut_dirty{};
|
||||||
|
bool lighting_lut_dirty_any = true;
|
||||||
|
bool fog_lut_dirty = true;
|
||||||
|
bool proctex_noise_lut_dirty = true;
|
||||||
|
bool proctex_color_map_dirty = true;
|
||||||
|
bool proctex_alpha_map_dirty = true;
|
||||||
|
bool proctex_lut_dirty = true;
|
||||||
|
bool proctex_diff_lut_dirty = true;
|
||||||
|
bool dirty = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
std::array<u16, 0x30000> cached_pages{};
|
std::array<u16, 0x30000> cached_pages{};
|
||||||
|
|
||||||
|
UniformBlockData uniform_block_data{};
|
||||||
|
std::array<std::array<Common::Vec2f, 256>, Pica::LightingRegs::NumLightingSampler>
|
||||||
|
lighting_lut_data{};
|
||||||
|
std::array<Common::Vec2f, 128> fog_lut_data{};
|
||||||
|
std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
|
||||||
|
std::array<Common::Vec2f, 128> proctex_color_map_data{};
|
||||||
|
std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
|
||||||
|
std::array<Common::Vec4f, 256> proctex_lut_data{};
|
||||||
|
std::array<Common::Vec4f, 256> proctex_diff_lut_data{};
|
||||||
};
|
};
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
@ -71,19 +71,6 @@ RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window, Driver& driv
|
|||||||
sw_vao.Create();
|
sw_vao.Create();
|
||||||
hw_vao.Create();
|
hw_vao.Create();
|
||||||
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
|
|
||||||
uniform_block_data.lighting_lut_dirty.fill(true);
|
|
||||||
uniform_block_data.lighting_lut_dirty_any = true;
|
|
||||||
|
|
||||||
uniform_block_data.fog_lut_dirty = true;
|
|
||||||
|
|
||||||
uniform_block_data.proctex_noise_lut_dirty = true;
|
|
||||||
uniform_block_data.proctex_color_map_dirty = true;
|
|
||||||
uniform_block_data.proctex_alpha_map_dirty = true;
|
|
||||||
uniform_block_data.proctex_lut_dirty = true;
|
|
||||||
uniform_block_data.proctex_diff_lut_dirty = true;
|
|
||||||
|
|
||||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
|
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
|
||||||
uniform_size_aligned_vs =
|
uniform_size_aligned_vs =
|
||||||
Common::AlignUp<std::size_t>(sizeof(VSUniformData), uniform_buffer_alignment);
|
Common::AlignUp<std::size_t>(sizeof(VSUniformData), uniform_buffer_alignment);
|
||||||
@ -1653,24 +1640,6 @@ void RasterizerOpenGL::SyncCullMode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncDepthScale() {
|
|
||||||
float depth_scale =
|
|
||||||
Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32();
|
|
||||||
if (depth_scale != uniform_block_data.data.depth_scale) {
|
|
||||||
uniform_block_data.data.depth_scale = depth_scale;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncDepthOffset() {
|
|
||||||
float depth_offset =
|
|
||||||
Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32();
|
|
||||||
if (depth_offset != uniform_block_data.data.depth_offset) {
|
|
||||||
uniform_block_data.data.depth_offset = depth_offset;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncBlendEnabled() {
|
void RasterizerOpenGL::SyncBlendEnabled() {
|
||||||
state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1);
|
state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1);
|
||||||
}
|
}
|
||||||
@ -1700,51 +1669,6 @@ void RasterizerOpenGL::SyncBlendColor() {
|
|||||||
state.blend.color.alpha = blend_color[3];
|
state.blend.color.alpha = blend_color[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncFogColor() {
|
|
||||||
const auto& regs = Pica::g_state.regs;
|
|
||||||
uniform_block_data.data.fog_color = {
|
|
||||||
regs.texturing.fog_color.r.Value() / 255.0f,
|
|
||||||
regs.texturing.fog_color.g.Value() / 255.0f,
|
|
||||||
regs.texturing.fog_color.b.Value() / 255.0f,
|
|
||||||
};
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncProcTexNoise() {
|
|
||||||
const auto& regs = Pica::g_state.regs.texturing;
|
|
||||||
uniform_block_data.data.proctex_noise_f = {
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(),
|
|
||||||
};
|
|
||||||
uniform_block_data.data.proctex_noise_a = {
|
|
||||||
regs.proctex_noise_u.amplitude / 4095.0f,
|
|
||||||
regs.proctex_noise_v.amplitude / 4095.0f,
|
|
||||||
};
|
|
||||||
uniform_block_data.data.proctex_noise_p = {
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(),
|
|
||||||
};
|
|
||||||
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncProcTexBias() {
|
|
||||||
const auto& regs = Pica::g_state.regs.texturing;
|
|
||||||
uniform_block_data.data.proctex_bias =
|
|
||||||
Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8))
|
|
||||||
.ToFloat32();
|
|
||||||
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncAlphaTest() {
|
|
||||||
const auto& regs = Pica::g_state.regs;
|
|
||||||
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
|
||||||
uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLogicOp() {
|
void RasterizerOpenGL::SyncLogicOp() {
|
||||||
const auto& regs = Pica::g_state.regs;
|
const auto& regs = Pica::g_state.regs;
|
||||||
state.logic_op = PicaToGL::LogicOp(regs.framebuffer.output_merger.logic_op);
|
state.logic_op = PicaToGL::LogicOp(regs.framebuffer.output_merger.logic_op);
|
||||||
@ -1828,131 +1752,6 @@ void RasterizerOpenGL::SyncDepthTest() {
|
|||||||
: GL_ALWAYS;
|
: GL_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncCombinerColor() {
|
|
||||||
auto combiner_color =
|
|
||||||
PicaToGL::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw);
|
|
||||||
if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) {
|
|
||||||
uniform_block_data.data.tev_combiner_buffer_color = combiner_color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncTevConstColor(std::size_t stage_index,
|
|
||||||
const Pica::TexturingRegs::TevStageConfig& tev_stage) {
|
|
||||||
const auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color);
|
|
||||||
|
|
||||||
if (const_color == uniform_block_data.data.const_color[stage_index]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uniform_block_data.data.const_color[stage_index] = const_color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncGlobalAmbient() {
|
|
||||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.global_ambient);
|
|
||||||
if (color != uniform_block_data.data.lighting_global_ambient) {
|
|
||||||
uniform_block_data.data.lighting_global_ambient = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightSpecular0(int light_index) {
|
|
||||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].specular_0) {
|
|
||||||
uniform_block_data.data.light_src[light_index].specular_0 = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightSpecular1(int light_index) {
|
|
||||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].specular_1) {
|
|
||||||
uniform_block_data.data.light_src[light_index].specular_1 = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightDiffuse(int light_index) {
|
|
||||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].diffuse) {
|
|
||||||
uniform_block_data.data.light_src[light_index].diffuse = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightAmbient(int light_index) {
|
|
||||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].ambient) {
|
|
||||||
uniform_block_data.data.light_src[light_index].ambient = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightPosition(int light_index) {
|
|
||||||
const auto& light = Pica::g_state.regs.lighting.light[light_index];
|
|
||||||
const Common::Vec3f position = {Pica::float16::FromRaw(light.x).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(light.y).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(light.z).ToFloat32()};
|
|
||||||
|
|
||||||
if (position != uniform_block_data.data.light_src[light_index].position) {
|
|
||||||
uniform_block_data.data.light_src[light_index].position = position;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightSpotDirection(int light_index) {
|
|
||||||
const auto& light = Pica::g_state.regs.lighting.light[light_index];
|
|
||||||
const auto spot_direction =
|
|
||||||
Common::Vec3f{light.spot_x / 2047.0f, light.spot_y / 2047.0f, light.spot_z / 2047.0f};
|
|
||||||
|
|
||||||
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.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) {
|
|
||||||
const auto& light = Pica::g_state.regs.lighting.light[light_index];
|
|
||||||
float dist_atten_bias = Pica::float20::FromRaw(light.dist_atten_bias).ToFloat32();
|
|
||||||
|
|
||||||
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.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) {
|
|
||||||
const auto& light = Pica::g_state.regs.lighting.light[light_index];
|
|
||||||
float dist_atten_scale = Pica::float20::FromRaw(light.dist_atten_scale).ToFloat32();
|
|
||||||
|
|
||||||
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.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncShadowBias() {
|
|
||||||
const auto& shadow = Pica::g_state.regs.framebuffer.shadow;
|
|
||||||
GLfloat constant = Pica::float16::FromRaw(shadow.constant).ToFloat32();
|
|
||||||
GLfloat linear = Pica::float16::FromRaw(shadow.linear).ToFloat32();
|
|
||||||
|
|
||||||
if (constant != uniform_block_data.data.shadow_bias_constant ||
|
|
||||||
linear != uniform_block_data.data.shadow_bias_linear) {
|
|
||||||
uniform_block_data.data.shadow_bias_constant = constant;
|
|
||||||
uniform_block_data.data.shadow_bias_linear = linear;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncShadowTextureBias() {
|
|
||||||
GLint bias = Pica::g_state.regs.texturing.shadow.bias << 1;
|
|
||||||
if (bias != uniform_block_data.data.shadow_texture_bias) {
|
|
||||||
uniform_block_data.data.shadow_texture_bias = bias;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncAndUploadLUTsLF() {
|
void RasterizerOpenGL::SyncAndUploadLUTsLF() {
|
||||||
constexpr std::size_t max_size =
|
constexpr std::size_t max_size =
|
||||||
sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler +
|
sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler +
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "common/vector_math.h"
|
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
#include "video_core/pica_types.h"
|
#include "video_core/pica_types.h"
|
||||||
#include "video_core/rasterizer_accelerated.h"
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
#include "video_core/regs_lighting.h"
|
|
||||||
#include "video_core/regs_texturing.h"
|
|
||||||
#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"
|
||||||
@ -133,12 +131,6 @@ private:
|
|||||||
/// Syncs the cull mode to match the PICA register
|
/// Syncs the cull mode to match the PICA register
|
||||||
void SyncCullMode();
|
void SyncCullMode();
|
||||||
|
|
||||||
/// Syncs the depth scale to match the PICA register
|
|
||||||
void SyncDepthScale();
|
|
||||||
|
|
||||||
/// Syncs the depth offset to match the PICA register
|
|
||||||
void SyncDepthOffset();
|
|
||||||
|
|
||||||
/// Syncs the blend enabled status to match the PICA register
|
/// Syncs the blend enabled status to match the PICA register
|
||||||
void SyncBlendEnabled();
|
void SyncBlendEnabled();
|
||||||
|
|
||||||
@ -148,18 +140,6 @@ private:
|
|||||||
/// Syncs the blend color to match the PICA register
|
/// Syncs the blend color to match the PICA register
|
||||||
void SyncBlendColor();
|
void SyncBlendColor();
|
||||||
|
|
||||||
/// Syncs the fog states to match the PICA register
|
|
||||||
void SyncFogColor();
|
|
||||||
|
|
||||||
/// Sync the procedural texture noise configuration to match the PICA register
|
|
||||||
void SyncProcTexNoise();
|
|
||||||
|
|
||||||
/// Sync the procedural texture bias configuration to match the PICA register
|
|
||||||
void SyncProcTexBias();
|
|
||||||
|
|
||||||
/// Syncs the alpha test states to match the PICA register
|
|
||||||
void SyncAlphaTest();
|
|
||||||
|
|
||||||
/// Syncs the logic op states to match the PICA register
|
/// Syncs the logic op states to match the PICA register
|
||||||
void SyncLogicOp();
|
void SyncLogicOp();
|
||||||
|
|
||||||
@ -178,46 +158,6 @@ private:
|
|||||||
/// Syncs the depth test states to match the PICA register
|
/// Syncs the depth test states to match the PICA register
|
||||||
void SyncDepthTest();
|
void SyncDepthTest();
|
||||||
|
|
||||||
/// Syncs the TEV combiner color buffer to match the PICA register
|
|
||||||
void SyncCombinerColor();
|
|
||||||
|
|
||||||
/// Syncs the TEV constant color to match the PICA register
|
|
||||||
void SyncTevConstColor(std::size_t tev_index,
|
|
||||||
const Pica::TexturingRegs::TevStageConfig& tev_stage);
|
|
||||||
|
|
||||||
/// Syncs the lighting global ambient color to match the PICA register
|
|
||||||
void SyncGlobalAmbient();
|
|
||||||
|
|
||||||
/// Syncs the specified light's specular 0 color to match the PICA register
|
|
||||||
void SyncLightSpecular0(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's specular 1 color to match the PICA register
|
|
||||||
void SyncLightSpecular1(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's diffuse color to match the PICA register
|
|
||||||
void SyncLightDiffuse(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's ambient color to match the PICA register
|
|
||||||
void SyncLightAmbient(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's position to match the PICA register
|
|
||||||
void SyncLightPosition(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified spot light direcition to match the PICA register
|
|
||||||
void SyncLightSpotDirection(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's distance attenuation bias to match the PICA register
|
|
||||||
void SyncLightDistanceAttenuationBias(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's distance attenuation scale to match the PICA register
|
|
||||||
void SyncLightDistanceAttenuationScale(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the shadow rendering bias to match the PICA register
|
|
||||||
void SyncShadowBias();
|
|
||||||
|
|
||||||
/// Syncs the shadow texture bias to match the PICA register
|
|
||||||
void SyncShadowTextureBias();
|
|
||||||
|
|
||||||
/// Syncs and uploads the lighting, fog and proctex LUTs
|
/// Syncs and uploads the lighting, fog and proctex LUTs
|
||||||
void SyncAndUploadLUTs();
|
void SyncAndUploadLUTs();
|
||||||
void SyncAndUploadLUTsLF();
|
void SyncAndUploadLUTsLF();
|
||||||
@ -263,19 +203,6 @@ private:
|
|||||||
bool is_amd;
|
bool is_amd;
|
||||||
bool shader_dirty = true;
|
bool shader_dirty = true;
|
||||||
|
|
||||||
struct {
|
|
||||||
UniformData data;
|
|
||||||
std::array<bool, Pica::LightingRegs::NumLightingSampler> lighting_lut_dirty;
|
|
||||||
bool lighting_lut_dirty_any;
|
|
||||||
bool fog_lut_dirty;
|
|
||||||
bool proctex_noise_lut_dirty;
|
|
||||||
bool proctex_color_map_dirty;
|
|
||||||
bool proctex_alpha_map_dirty;
|
|
||||||
bool proctex_lut_dirty;
|
|
||||||
bool proctex_diff_lut_dirty;
|
|
||||||
bool dirty;
|
|
||||||
} uniform_block_data = {};
|
|
||||||
|
|
||||||
std::unique_ptr<ShaderProgramManager> shader_program_manager;
|
std::unique_ptr<ShaderProgramManager> shader_program_manager;
|
||||||
|
|
||||||
// They shall be big enough for about one frame.
|
// They shall be big enough for about one frame.
|
||||||
@ -304,15 +231,6 @@ private:
|
|||||||
OGLTexture texture_buffer_lut_lf;
|
OGLTexture texture_buffer_lut_lf;
|
||||||
OGLTexture texture_buffer_lut_rg;
|
OGLTexture texture_buffer_lut_rg;
|
||||||
OGLTexture texture_buffer_lut_rgba;
|
OGLTexture texture_buffer_lut_rgba;
|
||||||
|
|
||||||
std::array<std::array<Common::Vec2f, 256>, Pica::LightingRegs::NumLightingSampler>
|
|
||||||
lighting_lut_data{};
|
|
||||||
std::array<Common::Vec2f, 128> fog_lut_data{};
|
|
||||||
std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
|
|
||||||
std::array<Common::Vec2f, 128> proctex_color_map_data{};
|
|
||||||
std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
|
|
||||||
std::array<Common::Vec4f, 256> proctex_lut_data{};
|
|
||||||
std::array<Common::Vec4f, 256> proctex_diff_lut_data{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
@ -132,8 +132,6 @@ RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instan
|
|||||||
null_surface.Transition(vk::ImageLayout::eShaderReadOnlyOptimal, 0, 1);
|
null_surface.Transition(vk::ImageLayout::eShaderReadOnlyOptimal, 0, 1);
|
||||||
null_storage_surface.Transition(vk::ImageLayout::eGeneral, 0, 1);
|
null_storage_surface.Transition(vk::ImageLayout::eGeneral, 0, 1);
|
||||||
|
|
||||||
uniform_block_data.lighting_lut_dirty.fill(true);
|
|
||||||
|
|
||||||
uniform_buffer_alignment = instance.UniformMinAlignment();
|
uniform_buffer_alignment = instance.UniformMinAlignment();
|
||||||
uniform_size_aligned_vs =
|
uniform_size_aligned_vs =
|
||||||
Common::AlignUp<std::size_t>(sizeof(Pica::Shader::VSUniformData), uniform_buffer_alignment);
|
Common::AlignUp<std::size_t>(sizeof(Pica::Shader::VSUniformData), uniform_buffer_alignment);
|
||||||
@ -1694,26 +1692,6 @@ void RasterizerVulkan::SyncCullMode() {
|
|||||||
pipeline_info.rasterization.cull_mode.Assign(regs.rasterizer.cull_mode);
|
pipeline_info.rasterization.cull_mode.Assign(regs.rasterizer.cull_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncDepthScale() {
|
|
||||||
float depth_scale =
|
|
||||||
Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32();
|
|
||||||
|
|
||||||
if (depth_scale != uniform_block_data.data.depth_scale) {
|
|
||||||
uniform_block_data.data.depth_scale = depth_scale;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncDepthOffset() {
|
|
||||||
float depth_offset =
|
|
||||||
Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32();
|
|
||||||
|
|
||||||
if (depth_offset != uniform_block_data.data.depth_offset) {
|
|
||||||
uniform_block_data.data.depth_offset = depth_offset;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncBlendEnabled() {
|
void RasterizerVulkan::SyncBlendEnabled() {
|
||||||
pipeline_info.blending.blend_enable.Assign(
|
pipeline_info.blending.blend_enable.Assign(
|
||||||
Pica::g_state.regs.framebuffer.output_merger.alphablend_enable);
|
Pica::g_state.regs.framebuffer.output_merger.alphablend_enable);
|
||||||
@ -1745,51 +1723,6 @@ void RasterizerVulkan::SyncBlendColor() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncFogColor() {
|
|
||||||
const auto& regs = Pica::g_state.regs;
|
|
||||||
uniform_block_data.data.fog_color = {
|
|
||||||
regs.texturing.fog_color.r.Value() / 255.0f,
|
|
||||||
regs.texturing.fog_color.g.Value() / 255.0f,
|
|
||||||
regs.texturing.fog_color.b.Value() / 255.0f,
|
|
||||||
};
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncProcTexNoise() {
|
|
||||||
const auto& regs = Pica::g_state.regs.texturing;
|
|
||||||
uniform_block_data.data.proctex_noise_f = {
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(),
|
|
||||||
};
|
|
||||||
uniform_block_data.data.proctex_noise_a = {
|
|
||||||
regs.proctex_noise_u.amplitude / 4095.0f,
|
|
||||||
regs.proctex_noise_v.amplitude / 4095.0f,
|
|
||||||
};
|
|
||||||
uniform_block_data.data.proctex_noise_p = {
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(),
|
|
||||||
};
|
|
||||||
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncProcTexBias() {
|
|
||||||
const auto& regs = Pica::g_state.regs.texturing;
|
|
||||||
uniform_block_data.data.proctex_bias =
|
|
||||||
Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8))
|
|
||||||
.ToFloat32();
|
|
||||||
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncAlphaTest() {
|
|
||||||
const auto& regs = Pica::g_state.regs;
|
|
||||||
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
|
||||||
uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLogicOp() {
|
void RasterizerVulkan::SyncLogicOp() {
|
||||||
const auto& regs = Pica::g_state.regs;
|
const auto& regs = Pica::g_state.regs;
|
||||||
pipeline_info.blending.logic_op.Assign(regs.framebuffer.output_merger.logic_op);
|
pipeline_info.blending.logic_op.Assign(regs.framebuffer.output_merger.logic_op);
|
||||||
@ -1846,132 +1779,6 @@ void RasterizerVulkan::SyncDepthTest() {
|
|||||||
pipeline_info.depth_stencil.depth_compare_op.Assign(compare_op);
|
pipeline_info.depth_stencil.depth_compare_op.Assign(compare_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncCombinerColor() {
|
|
||||||
auto combiner_color =
|
|
||||||
PicaToVK::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw);
|
|
||||||
if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) {
|
|
||||||
uniform_block_data.data.tev_combiner_buffer_color = combiner_color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncTevConstColor(std::size_t stage_index,
|
|
||||||
const Pica::TexturingRegs::TevStageConfig& tev_stage) {
|
|
||||||
const auto const_color = PicaToVK::ColorRGBA8(tev_stage.const_color);
|
|
||||||
|
|
||||||
if (const_color == uniform_block_data.data.const_color[stage_index]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uniform_block_data.data.const_color[stage_index] = const_color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncGlobalAmbient() {
|
|
||||||
auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.global_ambient);
|
|
||||||
if (color != uniform_block_data.data.lighting_global_ambient) {
|
|
||||||
uniform_block_data.data.lighting_global_ambient = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightSpecular0(int light_index) {
|
|
||||||
auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].specular_0) {
|
|
||||||
uniform_block_data.data.light_src[light_index].specular_0 = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightSpecular1(int light_index) {
|
|
||||||
auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].specular_1) {
|
|
||||||
uniform_block_data.data.light_src[light_index].specular_1 = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightDiffuse(int light_index) {
|
|
||||||
auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].diffuse) {
|
|
||||||
uniform_block_data.data.light_src[light_index].diffuse = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightAmbient(int light_index) {
|
|
||||||
auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient);
|
|
||||||
if (color != uniform_block_data.data.light_src[light_index].ambient) {
|
|
||||||
uniform_block_data.data.light_src[light_index].ambient = color;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightPosition(int light_index) {
|
|
||||||
const Common::Vec3f position = {
|
|
||||||
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(),
|
|
||||||
Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()};
|
|
||||||
|
|
||||||
if (position != uniform_block_data.data.light_src[light_index].position) {
|
|
||||||
uniform_block_data.data.light_src[light_index].position = position;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightSpotDirection(int light_index) {
|
|
||||||
const auto& light = Pica::g_state.regs.lighting.light[light_index];
|
|
||||||
const auto spot_direction = Common::Vec3i{light.spot_x, light.spot_y, light.spot_z} / 2047.0f;
|
|
||||||
|
|
||||||
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.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightDistanceAttenuationBias(int light_index) {
|
|
||||||
float dist_atten_bias =
|
|
||||||
Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias)
|
|
||||||
.ToFloat32();
|
|
||||||
|
|
||||||
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.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLightDistanceAttenuationScale(int light_index) {
|
|
||||||
float dist_atten_scale =
|
|
||||||
Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale)
|
|
||||||
.ToFloat32();
|
|
||||||
|
|
||||||
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.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncShadowBias() {
|
|
||||||
const auto& shadow = Pica::g_state.regs.framebuffer.shadow;
|
|
||||||
float constant = Pica::float16::FromRaw(shadow.constant).ToFloat32();
|
|
||||||
float linear = Pica::float16::FromRaw(shadow.linear).ToFloat32();
|
|
||||||
|
|
||||||
if (constant != uniform_block_data.data.shadow_bias_constant ||
|
|
||||||
linear != uniform_block_data.data.shadow_bias_linear) {
|
|
||||||
uniform_block_data.data.shadow_bias_constant = constant;
|
|
||||||
uniform_block_data.data.shadow_bias_linear = linear;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncShadowTextureBias() {
|
|
||||||
int bias = Pica::g_state.regs.texturing.shadow.bias << 1;
|
|
||||||
if (bias != uniform_block_data.data.shadow_texture_bias) {
|
|
||||||
uniform_block_data.data.shadow_texture_bias = bias;
|
|
||||||
uniform_block_data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerVulkan::SyncAndUploadLUTsLF() {
|
void RasterizerVulkan::SyncAndUploadLUTsLF() {
|
||||||
constexpr std::size_t max_size =
|
constexpr std::size_t max_size =
|
||||||
sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler +
|
sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler +
|
||||||
|
@ -4,16 +4,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/vector_math.h"
|
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
#include "video_core/rasterizer_accelerated.h"
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
#include "video_core/regs_lighting.h"
|
|
||||||
#include "video_core/regs_texturing.h"
|
|
||||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_stream_buffer.h"
|
#include "video_core/renderer_vulkan/vk_stream_buffer.h"
|
||||||
#include "video_core/renderer_vulkan/vk_texture_runtime.h"
|
#include "video_core/renderer_vulkan/vk_texture_runtime.h"
|
||||||
#include "video_core/shader/shader.h"
|
#include "video_core/shader/shader.h"
|
||||||
#include "video_core/shader/shader_uniforms.h"
|
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
@ -125,12 +121,6 @@ private:
|
|||||||
/// Syncs the cull mode to match the PICA register
|
/// Syncs the cull mode to match the PICA register
|
||||||
void SyncCullMode();
|
void SyncCullMode();
|
||||||
|
|
||||||
/// Syncs the depth scale to match the PICA register
|
|
||||||
void SyncDepthScale();
|
|
||||||
|
|
||||||
/// Syncs the depth offset to match the PICA register
|
|
||||||
void SyncDepthOffset();
|
|
||||||
|
|
||||||
/// Syncs the blend enabled status to match the PICA register
|
/// Syncs the blend enabled status to match the PICA register
|
||||||
void SyncBlendEnabled();
|
void SyncBlendEnabled();
|
||||||
|
|
||||||
@ -140,18 +130,6 @@ private:
|
|||||||
/// Syncs the blend color to match the PICA register
|
/// Syncs the blend color to match the PICA register
|
||||||
void SyncBlendColor();
|
void SyncBlendColor();
|
||||||
|
|
||||||
/// Syncs the fog states to match the PICA register
|
|
||||||
void SyncFogColor();
|
|
||||||
|
|
||||||
/// Sync the procedural texture noise configuration to match the PICA register
|
|
||||||
void SyncProcTexNoise();
|
|
||||||
|
|
||||||
/// Sync the procedural texture bias configuration to match the PICA register
|
|
||||||
void SyncProcTexBias();
|
|
||||||
|
|
||||||
/// Syncs the alpha test states to match the PICA register
|
|
||||||
void SyncAlphaTest();
|
|
||||||
|
|
||||||
/// Syncs the logic op states to match the PICA register
|
/// Syncs the logic op states to match the PICA register
|
||||||
void SyncLogicOp();
|
void SyncLogicOp();
|
||||||
|
|
||||||
@ -170,46 +148,6 @@ private:
|
|||||||
/// Syncs the depth test states to match the PICA register
|
/// Syncs the depth test states to match the PICA register
|
||||||
void SyncDepthTest();
|
void SyncDepthTest();
|
||||||
|
|
||||||
/// Syncs the TEV combiner color buffer to match the PICA register
|
|
||||||
void SyncCombinerColor();
|
|
||||||
|
|
||||||
/// Syncs the TEV constant color to match the PICA register
|
|
||||||
void SyncTevConstColor(std::size_t tev_index,
|
|
||||||
const Pica::TexturingRegs::TevStageConfig& tev_stage);
|
|
||||||
|
|
||||||
/// Syncs the lighting global ambient color to match the PICA register
|
|
||||||
void SyncGlobalAmbient();
|
|
||||||
|
|
||||||
/// Syncs the specified light's specular 0 color to match the PICA register
|
|
||||||
void SyncLightSpecular0(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's specular 1 color to match the PICA register
|
|
||||||
void SyncLightSpecular1(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's diffuse color to match the PICA register
|
|
||||||
void SyncLightDiffuse(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's ambient color to match the PICA register
|
|
||||||
void SyncLightAmbient(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's position to match the PICA register
|
|
||||||
void SyncLightPosition(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified spot light direcition to match the PICA register
|
|
||||||
void SyncLightSpotDirection(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's distance attenuation bias to match the PICA register
|
|
||||||
void SyncLightDistanceAttenuationBias(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's distance attenuation scale to match the PICA register
|
|
||||||
void SyncLightDistanceAttenuationScale(int light_index);
|
|
||||||
|
|
||||||
/// Syncs the shadow rendering bias to match the PICA register
|
|
||||||
void SyncShadowBias();
|
|
||||||
|
|
||||||
/// Syncs the shadow texture bias to match the PICA register
|
|
||||||
void SyncShadowTextureBias();
|
|
||||||
|
|
||||||
/// Syncs and uploads the lighting, fog and proctex LUTs
|
/// Syncs and uploads the lighting, fog and proctex LUTs
|
||||||
void SyncAndUploadLUTs();
|
void SyncAndUploadLUTs();
|
||||||
void SyncAndUploadLUTsLF();
|
void SyncAndUploadLUTsLF();
|
||||||
@ -283,19 +221,6 @@ private:
|
|||||||
Surface null_surface;
|
Surface null_surface;
|
||||||
Surface null_storage_surface;
|
Surface null_storage_surface;
|
||||||
|
|
||||||
struct {
|
|
||||||
Pica::Shader::UniformData data{};
|
|
||||||
std::array<bool, Pica::LightingRegs::NumLightingSampler> lighting_lut_dirty{};
|
|
||||||
bool lighting_lut_dirty_any = true;
|
|
||||||
bool fog_lut_dirty = true;
|
|
||||||
bool proctex_noise_lut_dirty = true;
|
|
||||||
bool proctex_color_map_dirty = true;
|
|
||||||
bool proctex_alpha_map_dirty = true;
|
|
||||||
bool proctex_lut_dirty = true;
|
|
||||||
bool proctex_diff_lut_dirty = true;
|
|
||||||
bool dirty = true;
|
|
||||||
} uniform_block_data = {};
|
|
||||||
|
|
||||||
std::array<SamplerInfo, 3> texture_samplers;
|
std::array<SamplerInfo, 3> texture_samplers;
|
||||||
SamplerInfo texture_cube_sampler;
|
SamplerInfo texture_cube_sampler;
|
||||||
std::unordered_map<SamplerInfo, vk::Sampler> samplers;
|
std::unordered_map<SamplerInfo, vk::Sampler> samplers;
|
||||||
@ -310,15 +235,6 @@ private:
|
|||||||
std::size_t uniform_buffer_alignment;
|
std::size_t uniform_buffer_alignment;
|
||||||
std::size_t uniform_size_aligned_vs;
|
std::size_t uniform_size_aligned_vs;
|
||||||
std::size_t uniform_size_aligned_fs;
|
std::size_t uniform_size_aligned_fs;
|
||||||
|
|
||||||
std::array<std::array<Common::Vec2f, 256>, Pica::LightingRegs::NumLightingSampler>
|
|
||||||
lighting_lut_data{};
|
|
||||||
std::array<Common::Vec2f, 128> fog_lut_data{};
|
|
||||||
std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
|
|
||||||
std::array<Common::Vec2f, 128> proctex_color_map_data{};
|
|
||||||
std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
|
|
||||||
std::array<Common::Vec4f, 256> proctex_lut_data{};
|
|
||||||
std::array<Common::Vec4f, 256> proctex_diff_lut_data{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
Reference in New Issue
Block a user