diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 07465c71d..436b2515c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -409,10 +409,9 @@ bool PipelineCache::UseProgrammableVertexShader(const Pica::RegsInternal& regs, std::vector code; - // Disabled for programmable shaders for now if (use_spirv && false) { - // Directly generate SPIRV - code = SPIRV::GenerateVertexShader(setup, config, profile); + // TODO: Generate vertex shader SPIRV from the given VS program + // code = SPIRV::GenerateVertexShader(setup, config, profile); } else { // Generate GLSL const std::string program = GLSL::GenerateVertexShader(setup, config, true); @@ -427,7 +426,7 @@ bool PipelineCache::UseProgrammableVertexShader(const Pica::RegsInternal& regs, const u64 code_hash = Common::ComputeHash64(std::as_bytes(std::span(code))); - auto [iter, new_program] = programmable_vertex_cache.try_emplace(code_hash, instance); + const auto [iter, new_program] = programmable_vertex_cache.try_emplace(code_hash, instance); auto& shader = iter->second; // Queue worker thread to create shader module diff --git a/src/video_core/shader/generator/spv_fs_shader_gen.h b/src/video_core/shader/generator/spv_fs_shader_gen.h index ecca1d842..ad0ebc57a 100644 --- a/src/video_core/shader/generator/spv_fs_shader_gen.h +++ b/src/video_core/shader/generator/spv_fs_shader_gen.h @@ -7,6 +7,7 @@ #include #include +#include "common/common_types.h" #include "spv_shader_gen.h" #include "video_core/pica/regs_framebuffer.h" #include "video_core/pica/regs_texturing.h" diff --git a/src/video_core/shader/generator/spv_shader_gen.cpp b/src/video_core/shader/generator/spv_shader_gen.cpp index f4a0c7420..98557422b 100644 --- a/src/video_core/shader/generator/spv_shader_gen.cpp +++ b/src/video_core/shader/generator/spv_shader_gen.cpp @@ -209,83 +209,69 @@ void VertexModule::Generate(Common::UniqueFunction GenerateTrivialVertexShader(bool use_clip_planes) { VertexModule module; - module.Generate([use_clip_planes](Sirit::Module& code, + module.Generate([use_clip_planes](Sirit::Module& spv, const VertexModule::EmitterIDs& ids) -> void { - const Id pos_sanitized = code.OpFunctionCall( - ids.vec.Get(4), ids.sanitize_vertex, code.OpLoad(ids.vec.Get(4), ids.vert_in_position)); + const Id pos_sanitized = spv.OpFunctionCall( + ids.vec.Get(4), ids.sanitize_vertex, spv.OpLoad(ids.vec.Get(4), ids.vert_in_position)); // Negate Z - const Id neg_z = - code.OpFNegate(ids.f32, code.OpCompositeExtract(ids.f32, pos_sanitized, 2)); - const Id negated_z = code.OpCompositeInsert(ids.vec.Get(4), neg_z, pos_sanitized, 2); + const Id neg_z = spv.OpFNegate(ids.f32, spv.OpCompositeExtract(ids.f32, pos_sanitized, 2)); + const Id negated_z = spv.OpCompositeInsert(ids.vec.Get(4), neg_z, pos_sanitized, 2); - code.OpStore(ids.gl_position, negated_z); + spv.OpStore(ids.gl_position, negated_z); // Pass-through - code.OpStore(ids.vert_out_color, code.OpLoad(ids.vec.Get(4), ids.vert_in_color)); - code.OpStore(ids.vert_out_texcoord0, code.OpLoad(ids.vec.Get(2), ids.vert_in_texcoord0)); - code.OpStore(ids.vert_out_texcoord1, code.OpLoad(ids.vec.Get(2), ids.vert_in_texcoord1)); - code.OpStore(ids.vert_out_texcoord2, code.OpLoad(ids.vec.Get(2), ids.vert_in_texcoord2)); - code.OpStore(ids.vert_out_texcoord0_w, code.OpLoad(ids.f32, ids.vert_in_texcoord0_w)); - code.OpStore(ids.vert_out_normquat, code.OpLoad(ids.vec.Get(4), ids.vert_in_normquat)); - code.OpStore(ids.vert_out_view, code.OpLoad(ids.vec.Get(3), ids.vert_in_view)); + spv.OpStore(ids.vert_out_color, spv.OpLoad(ids.vec.Get(4), ids.vert_in_color)); + spv.OpStore(ids.vert_out_texcoord0, spv.OpLoad(ids.vec.Get(2), ids.vert_in_texcoord0)); + spv.OpStore(ids.vert_out_texcoord1, spv.OpLoad(ids.vec.Get(2), ids.vert_in_texcoord1)); + spv.OpStore(ids.vert_out_texcoord2, spv.OpLoad(ids.vec.Get(2), ids.vert_in_texcoord2)); + spv.OpStore(ids.vert_out_texcoord0_w, spv.OpLoad(ids.f32, ids.vert_in_texcoord0_w)); + spv.OpStore(ids.vert_out_normquat, spv.OpLoad(ids.vec.Get(4), ids.vert_in_normquat)); + spv.OpStore(ids.vert_out_view, spv.OpLoad(ids.vec.Get(3), ids.vert_in_view)); if (use_clip_planes) { - code.OpStore(code.OpAccessChain(code.TypePointer(spv::StorageClass::Output, ids.f32), - ids.gl_clip_distance, code.Constant(ids.u32, 0)), - neg_z); + spv.OpStore(spv.OpAccessChain(spv.TypePointer(spv::StorageClass::Output, ids.f32), + ids.gl_clip_distance, spv.Constant(ids.u32, 0)), + neg_z); - const Id enable_clip1 = code.OpINotEqual( - ids.bool_, code.OpLoad(ids.u32, ids.ptr_enable_clip1), code.Constant(ids.u32, 0)); + const Id enable_clip1 = spv.OpINotEqual( + ids.bool_, spv.OpLoad(ids.u32, ids.ptr_enable_clip1), spv.Constant(ids.u32, 0)); { - const Id true_label = code.OpLabel(); - const Id false_label = code.OpLabel(); - const Id end_label = code.OpLabel(); + const Id true_label = spv.OpLabel(); + const Id false_label = spv.OpLabel(); + const Id end_label = spv.OpLabel(); - code.OpSelectionMerge(end_label, spv::SelectionControlMask::MaskNone); - code.OpBranchConditional(enable_clip1, true_label, false_label); + spv.OpSelectionMerge(end_label, spv::SelectionControlMask::MaskNone); + spv.OpBranchConditional(enable_clip1, true_label, false_label); { - code.AddLabel(true_label); + spv.AddLabel(true_label); - code.OpStore( - code.OpAccessChain(code.TypePointer(spv::StorageClass::Output, ids.f32), - ids.gl_clip_distance, code.Constant(ids.u32, 1)), - code.OpDot(ids.f32, code.OpLoad(ids.vec.Get(4), ids.ptr_clip_coef), - pos_sanitized)); + spv.OpStore( + spv.OpAccessChain(spv.TypePointer(spv::StorageClass::Output, ids.f32), + ids.gl_clip_distance, spv.Constant(ids.u32, 1)), + spv.OpDot(ids.f32, spv.OpLoad(ids.vec.Get(4), ids.ptr_clip_coef), + pos_sanitized)); - code.OpBranch(end_label); + spv.OpBranch(end_label); } { - code.AddLabel(false_label); + spv.AddLabel(false_label); - code.OpStore( - code.OpAccessChain(code.TypePointer(spv::StorageClass::Output, ids.f32), - ids.gl_clip_distance, code.Constant(ids.u32, 1)), - code.ConstantNull(ids.f32)); + spv.OpStore( + spv.OpAccessChain(spv.TypePointer(spv::StorageClass::Output, ids.f32), + ids.gl_clip_distance, spv.Constant(ids.u32, 1)), + spv.ConstantNull(ids.f32)); - code.OpBranch(end_label); + spv.OpBranch(end_label); } - code.AddLabel(end_label); + spv.AddLabel(end_label); } } }); return module.Assemble(); } -std::vector GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& config, - const Profile& profile) { - VertexModule module; - module.Generate(config, profile); - return module.Assemble(); -} - } // namespace Pica::Shader::Generator::SPIRV \ No newline at end of file diff --git a/src/video_core/shader/generator/spv_shader_gen.h b/src/video_core/shader/generator/spv_shader_gen.h index 15709ee7e..d45cb19cf 100644 --- a/src/video_core/shader/generator/spv_shader_gen.h +++ b/src/video_core/shader/generator/spv_shader_gen.h @@ -66,10 +66,11 @@ private: void DefineEntryPoint(); void DefineInterface(); - Id WriteFuncSanitizeVertex(); + [[nodiscard]] Id WriteFuncSanitizeVertex(); public: struct EmitterIDs { + /// Types Id void_{}; Id bool_{}; Id f32{}; @@ -81,7 +82,7 @@ public: VectorIds uvec{}; VectorIds bvec{}; - // Input vertex attributes + /// Input vertex attributes Id vert_in_position{}; Id vert_in_color{}; Id vert_in_texcoord0{}; @@ -91,7 +92,7 @@ public: Id vert_in_normquat{}; Id vert_in_view{}; - // Output vertex attributes + /// Output vertex attributes Id vert_out_color{}; Id vert_out_texcoord0{}; Id vert_out_texcoord1{}; @@ -100,26 +101,23 @@ public: Id vert_out_normquat{}; Id vert_out_view{}; - // Uniforms + /// Uniforms // vs_data Id ptr_vs_data; Id ptr_enable_clip1; Id ptr_clip_coef; - // Built-ins + /// Built-ins Id gl_position; Id gl_clip_distance; - // Functions + /// Functions Id sanitize_vertex; } ids; /// Generate code using the provided SPIRV emitter context void Generate(Common::UniqueFunction proc); - - /// Emits SPIR-V bytecode corresponding to the provided pica vertex configuration - void Generate(const PicaVSConfig& config, const Profile& profile); }; /** @@ -129,12 +127,4 @@ public: */ std::vector GenerateTrivialVertexShader(bool use_clip_planes); -/** - * Generates the SPIRV vertex shader program source code for the given VS program - * @param config ShaderCacheKey object generated for the current Pica state, used for the shader - * configuration (NOTE: Use state in this struct only, not the Pica registers!) - * @returns SPIRV shader assembly; empty on failure - */ -std::vector GenerateVertexShader(const Pica::ShaderSetup& setup, const PicaVSConfig& config, - const Profile& profile); } // namespace Pica::Shader::Generator::SPIRV