video_core: Refactor GLSL fragment emitter (#7093)
* video_core: Refactor GLSL fragment emitter * shader: Add back custom normal maps
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "common/thread_worker.h"
|
||||
#include "video_core/rasterizer_cache/pixel_format.h"
|
||||
#include "video_core/regs_pipeline.h"
|
||||
#include "video_core/regs_rasterizer.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
#include "video_core/shader/generator/glsl_shader_gen.h"
|
||||
#include "video_core/shader/generator/spv_shader_gen.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
||||
@@ -15,8 +15,12 @@
|
||||
#include "video_core/renderer_vulkan/vk_renderpass_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "video_core/shader/generator/glsl_fs_shader_gen.h"
|
||||
#include "video_core/shader/generator/glsl_shader_gen.h"
|
||||
#include "video_core/shader/generator/spv_fs_shader_gen.h"
|
||||
|
||||
using namespace Pica::Shader::Generator;
|
||||
using Pica::Shader::FSConfig;
|
||||
|
||||
MICROPROFILE_DEFINE(Vulkan_Bind, "Vulkan", "Pipeline Bind", MP_RGB(192, 32, 32));
|
||||
|
||||
@@ -86,6 +90,17 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
||||
trivial_vertex_shader{
|
||||
instance, vk::ShaderStageFlagBits::eVertex,
|
||||
GLSL::GenerateTrivialVertexShader(instance.IsShaderClipDistanceSupported(), true)} {
|
||||
profile = Pica::Shader::Profile{
|
||||
.has_separable_shaders = true,
|
||||
.has_clip_planes = instance.IsShaderClipDistanceSupported(),
|
||||
.has_geometry_shader = instance.UseGeometryShaders(),
|
||||
.has_custom_border_color = instance.IsCustomBorderColorSupported(),
|
||||
.has_fragment_shader_interlock = instance.IsFragmentShaderInterlockSupported(),
|
||||
.has_blend_minmax_factor = false,
|
||||
.has_minus_one_to_one_range = false,
|
||||
.has_logic_op = !instance.NeedsLogicOpEmulation(),
|
||||
.is_vulkan = true,
|
||||
};
|
||||
BuildLayout();
|
||||
}
|
||||
|
||||
@@ -403,35 +418,30 @@ void PipelineCache::UseTrivialGeometryShader() {
|
||||
shader_hashes[ProgramType::GS] = 0;
|
||||
}
|
||||
|
||||
void PipelineCache::UseFragmentShader(const Pica::Regs& regs) {
|
||||
const PicaFSConfig config{regs, instance.IsFragmentShaderInterlockSupported(),
|
||||
instance.NeedsLogicOpEmulation(),
|
||||
!instance.IsCustomBorderColorSupported(), false};
|
||||
|
||||
const auto [it, new_shader] = fragment_shaders.try_emplace(config, instance);
|
||||
void PipelineCache::UseFragmentShader(const Pica::Regs& regs,
|
||||
const Pica::Shader::UserConfig& user) {
|
||||
const FSConfig fs_config{regs, user, profile};
|
||||
const auto [it, new_shader] = fragment_shaders.try_emplace(fs_config, instance);
|
||||
auto& shader = it->second;
|
||||
|
||||
if (new_shader) {
|
||||
const bool use_spirv = Settings::values.spirv_shader_gen.GetValue();
|
||||
const auto texture0_type = config.state.texture0_type.Value();
|
||||
const bool is_shadow = texture0_type == Pica::TexturingRegs::TextureConfig::Shadow2D ||
|
||||
texture0_type == Pica::TexturingRegs::TextureConfig::ShadowCube ||
|
||||
config.state.shadow_rendering.Value();
|
||||
if (use_spirv && !is_shadow) {
|
||||
const std::vector code = SPIRV::GenerateFragmentShader(config);
|
||||
if (use_spirv && !fs_config.UsesShadowPipeline()) {
|
||||
const std::vector code = SPIRV::GenerateFragmentShader(fs_config);
|
||||
shader.module = CompileSPV(code, instance.GetDevice());
|
||||
shader.MarkDone();
|
||||
} else {
|
||||
workers.QueueWork([config, device = instance.GetDevice(), &shader]() {
|
||||
const std::string code = GLSL::GenerateFragmentShader(config, true);
|
||||
shader.module = Compile(code, vk::ShaderStageFlagBits::eFragment, device);
|
||||
workers.QueueWork([fs_config, this, &shader]() {
|
||||
const std::string code = GLSL::GenerateFragmentShader(fs_config, profile);
|
||||
shader.module =
|
||||
Compile(code, vk::ShaderStageFlagBits::eFragment, instance.GetDevice());
|
||||
shader.MarkDone();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
current_shaders[ProgramType::FS] = &shader;
|
||||
shader_hashes[ProgramType::FS] = config.Hash();
|
||||
shader_hashes[ProgramType::FS] = fs_config.Hash();
|
||||
}
|
||||
|
||||
void PipelineCache::BindTexture(u32 binding, vk::ImageView image_view, vk::Sampler sampler) {
|
||||
|
||||
@@ -9,13 +9,18 @@
|
||||
|
||||
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
||||
#include "video_core/renderer_vulkan/vk_graphics_pipeline.h"
|
||||
#include "video_core/shader/generator/glsl_shader_gen.h"
|
||||
#include "video_core/shader/generator/spv_shader_gen.h"
|
||||
#include "video_core/shader/generator/pica_fs_config.h"
|
||||
#include "video_core/shader/generator/profile.h"
|
||||
#include "video_core/shader/generator/shader_gen.h"
|
||||
|
||||
namespace Pica {
|
||||
struct Regs;
|
||||
}
|
||||
|
||||
namespace Pica::Shader {
|
||||
struct ShaderSetup;
|
||||
}
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class Instance;
|
||||
@@ -62,7 +67,7 @@ public:
|
||||
void UseTrivialGeometryShader();
|
||||
|
||||
/// Binds a fragment shader generated from PICA state
|
||||
void UseFragmentShader(const Pica::Regs& regs);
|
||||
void UseFragmentShader(const Pica::Regs& regs, const Pica::Shader::UserConfig& user);
|
||||
|
||||
/// Binds a texture to the specified binding
|
||||
void BindTexture(u32 binding, vk::ImageView image_view, vk::Sampler sampler);
|
||||
@@ -98,6 +103,7 @@ private:
|
||||
RenderpassCache& renderpass_cache;
|
||||
DescriptorPool& pool;
|
||||
|
||||
Pica::Shader::Profile profile{};
|
||||
vk::UniquePipelineCache pipeline_cache;
|
||||
vk::UniquePipelineLayout pipeline_layout;
|
||||
std::size_t num_worker_threads;
|
||||
@@ -118,7 +124,7 @@ private:
|
||||
std::unordered_map<Pica::Shader::Generator::PicaVSConfig, Shader*> programmable_vertex_map;
|
||||
std::unordered_map<std::string, Shader> programmable_vertex_cache;
|
||||
std::unordered_map<Pica::Shader::Generator::PicaFixedGSConfig, Shader> fixed_geometry_shaders;
|
||||
std::unordered_map<Pica::Shader::Generator::PicaFSConfig, Shader> fragment_shaders;
|
||||
std::unordered_map<Pica::Shader::FSConfig, Shader> fragment_shaders;
|
||||
Shader trivial_vertex_shader;
|
||||
};
|
||||
|
||||
|
||||
@@ -497,7 +497,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
||||
|
||||
// Sync and bind the shader
|
||||
if (shader_dirty) {
|
||||
pipeline_cache.UseFragmentShader(regs);
|
||||
pipeline_cache.UseFragmentShader(regs, user_config);
|
||||
shader_dirty = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user