renderer_vulkan: Remove general vertex-spv generation interface

Keep this a `TODO` for now.
This commit is contained in:
Wunkolo 2024-03-03 13:49:52 -08:00
parent eaa5b74f5e
commit eb814f77c7
4 changed files with 48 additions and 72 deletions

View file

@ -409,10 +409,9 @@ bool PipelineCache::UseProgrammableVertexShader(const Pica::RegsInternal& regs,
std::vector<u32> code; std::vector<u32> code;
// Disabled for programmable shaders for now
if (use_spirv && false) { if (use_spirv && false) {
// Directly generate SPIRV // TODO: Generate vertex shader SPIRV from the given VS program
code = SPIRV::GenerateVertexShader(setup, config, profile); // code = SPIRV::GenerateVertexShader(setup, config, profile);
} else { } else {
// Generate GLSL // Generate GLSL
const std::string program = GLSL::GenerateVertexShader(setup, config, true); 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))); 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; auto& shader = iter->second;
// Queue worker thread to create shader module // Queue worker thread to create shader module

View file

@ -7,6 +7,7 @@
#include <array> #include <array>
#include <sirit/sirit.h> #include <sirit/sirit.h>
#include "common/common_types.h"
#include "spv_shader_gen.h" #include "spv_shader_gen.h"
#include "video_core/pica/regs_framebuffer.h" #include "video_core/pica/regs_framebuffer.h"
#include "video_core/pica/regs_texturing.h" #include "video_core/pica/regs_texturing.h"

View file

@ -209,83 +209,69 @@ void VertexModule::Generate(Common::UniqueFunction<void, Sirit::Module&, const E
OpFunctionEnd(); OpFunctionEnd();
} }
void VertexModule::Generate(const PicaVSConfig& config, const Profile& profile) {
AddLabel(OpLabel());
OpReturn();
OpFunctionEnd();
}
std::vector<u32> GenerateTrivialVertexShader(bool use_clip_planes) { std::vector<u32> GenerateTrivialVertexShader(bool use_clip_planes) {
VertexModule module; VertexModule module;
module.Generate([use_clip_planes](Sirit::Module& code, module.Generate([use_clip_planes](Sirit::Module& spv,
const VertexModule::EmitterIDs& ids) -> void { const VertexModule::EmitterIDs& ids) -> void {
const Id pos_sanitized = code.OpFunctionCall( const Id pos_sanitized = spv.OpFunctionCall(
ids.vec.Get(4), ids.sanitize_vertex, code.OpLoad(ids.vec.Get(4), ids.vert_in_position)); ids.vec.Get(4), ids.sanitize_vertex, spv.OpLoad(ids.vec.Get(4), ids.vert_in_position));
// Negate Z // Negate Z
const Id neg_z = const Id neg_z = spv.OpFNegate(ids.f32, spv.OpCompositeExtract(ids.f32, pos_sanitized, 2));
code.OpFNegate(ids.f32, code.OpCompositeExtract(ids.f32, pos_sanitized, 2)); const Id negated_z = spv.OpCompositeInsert(ids.vec.Get(4), neg_z, pos_sanitized, 2);
const Id negated_z = code.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 // Pass-through
code.OpStore(ids.vert_out_color, code.OpLoad(ids.vec.Get(4), ids.vert_in_color)); spv.OpStore(ids.vert_out_color, spv.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)); spv.OpStore(ids.vert_out_texcoord0, spv.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)); spv.OpStore(ids.vert_out_texcoord1, spv.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)); spv.OpStore(ids.vert_out_texcoord2, spv.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)); spv.OpStore(ids.vert_out_texcoord0_w, spv.OpLoad(ids.f32, ids.vert_in_texcoord0_w));
code.OpStore(ids.vert_out_normquat, code.OpLoad(ids.vec.Get(4), ids.vert_in_normquat)); spv.OpStore(ids.vert_out_normquat, spv.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_view, spv.OpLoad(ids.vec.Get(3), ids.vert_in_view));
if (use_clip_planes) { if (use_clip_planes) {
code.OpStore(code.OpAccessChain(code.TypePointer(spv::StorageClass::Output, ids.f32), spv.OpStore(spv.OpAccessChain(spv.TypePointer(spv::StorageClass::Output, ids.f32),
ids.gl_clip_distance, code.Constant(ids.u32, 0)), ids.gl_clip_distance, spv.Constant(ids.u32, 0)),
neg_z); neg_z);
const Id enable_clip1 = code.OpINotEqual( const Id enable_clip1 = spv.OpINotEqual(
ids.bool_, code.OpLoad(ids.u32, ids.ptr_enable_clip1), code.Constant(ids.u32, 0)); ids.bool_, spv.OpLoad(ids.u32, ids.ptr_enable_clip1), spv.Constant(ids.u32, 0));
{ {
const Id true_label = code.OpLabel(); const Id true_label = spv.OpLabel();
const Id false_label = code.OpLabel(); const Id false_label = spv.OpLabel();
const Id end_label = code.OpLabel(); const Id end_label = spv.OpLabel();
code.OpSelectionMerge(end_label, spv::SelectionControlMask::MaskNone); spv.OpSelectionMerge(end_label, spv::SelectionControlMask::MaskNone);
code.OpBranchConditional(enable_clip1, true_label, false_label); spv.OpBranchConditional(enable_clip1, true_label, false_label);
{ {
code.AddLabel(true_label); spv.AddLabel(true_label);
code.OpStore( spv.OpStore(
code.OpAccessChain(code.TypePointer(spv::StorageClass::Output, ids.f32), spv.OpAccessChain(spv.TypePointer(spv::StorageClass::Output, ids.f32),
ids.gl_clip_distance, code.Constant(ids.u32, 1)), ids.gl_clip_distance, spv.Constant(ids.u32, 1)),
code.OpDot(ids.f32, code.OpLoad(ids.vec.Get(4), ids.ptr_clip_coef), spv.OpDot(ids.f32, spv.OpLoad(ids.vec.Get(4), ids.ptr_clip_coef),
pos_sanitized)); pos_sanitized));
code.OpBranch(end_label); spv.OpBranch(end_label);
} }
{ {
code.AddLabel(false_label); spv.AddLabel(false_label);
code.OpStore( spv.OpStore(
code.OpAccessChain(code.TypePointer(spv::StorageClass::Output, ids.f32), spv.OpAccessChain(spv.TypePointer(spv::StorageClass::Output, ids.f32),
ids.gl_clip_distance, code.Constant(ids.u32, 1)), ids.gl_clip_distance, spv.Constant(ids.u32, 1)),
code.ConstantNull(ids.f32)); spv.ConstantNull(ids.f32));
code.OpBranch(end_label); spv.OpBranch(end_label);
} }
code.AddLabel(end_label); spv.AddLabel(end_label);
} }
} }
}); });
return module.Assemble(); return module.Assemble();
} }
std::vector<u32> GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& config,
const Profile& profile) {
VertexModule module;
module.Generate(config, profile);
return module.Assemble();
}
} // namespace Pica::Shader::Generator::SPIRV } // namespace Pica::Shader::Generator::SPIRV

View file

@ -66,10 +66,11 @@ private:
void DefineEntryPoint(); void DefineEntryPoint();
void DefineInterface(); void DefineInterface();
Id WriteFuncSanitizeVertex(); [[nodiscard]] Id WriteFuncSanitizeVertex();
public: public:
struct EmitterIDs { struct EmitterIDs {
/// Types
Id void_{}; Id void_{};
Id bool_{}; Id bool_{};
Id f32{}; Id f32{};
@ -81,7 +82,7 @@ public:
VectorIds uvec{}; VectorIds uvec{};
VectorIds bvec{}; VectorIds bvec{};
// Input vertex attributes /// Input vertex attributes
Id vert_in_position{}; Id vert_in_position{};
Id vert_in_color{}; Id vert_in_color{};
Id vert_in_texcoord0{}; Id vert_in_texcoord0{};
@ -91,7 +92,7 @@ public:
Id vert_in_normquat{}; Id vert_in_normquat{};
Id vert_in_view{}; Id vert_in_view{};
// Output vertex attributes /// Output vertex attributes
Id vert_out_color{}; Id vert_out_color{};
Id vert_out_texcoord0{}; Id vert_out_texcoord0{};
Id vert_out_texcoord1{}; Id vert_out_texcoord1{};
@ -100,26 +101,23 @@ public:
Id vert_out_normquat{}; Id vert_out_normquat{};
Id vert_out_view{}; Id vert_out_view{};
// Uniforms /// Uniforms
// vs_data // vs_data
Id ptr_vs_data; Id ptr_vs_data;
Id ptr_enable_clip1; Id ptr_enable_clip1;
Id ptr_clip_coef; Id ptr_clip_coef;
// Built-ins /// Built-ins
Id gl_position; Id gl_position;
Id gl_clip_distance; Id gl_clip_distance;
// Functions /// Functions
Id sanitize_vertex; Id sanitize_vertex;
} ids; } ids;
/// Generate code using the provided SPIRV emitter context /// Generate code using the provided SPIRV emitter context
void Generate(Common::UniqueFunction<void, Sirit::Module&, const EmitterIDs&> proc); void Generate(Common::UniqueFunction<void, Sirit::Module&, const EmitterIDs&> 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<u32> GenerateTrivialVertexShader(bool use_clip_planes); std::vector<u32> 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<u32> GenerateVertexShader(const Pica::ShaderSetup& setup, const PicaVSConfig& config,
const Profile& profile);
} // namespace Pica::Shader::Generator::SPIRV } // namespace Pica::Shader::Generator::SPIRV