renderer_vulkan: Remove general vertex-spv generation interface
Keep this a `TODO` for now.
This commit is contained in:
parent
eaa5b74f5e
commit
eb814f77c7
4 changed files with 48 additions and 72 deletions
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue