summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/spirv/emit_spirv.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-03-20 23:11:56 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:23 +0200
commit76c8a962ac4eae77e71d66a72c448930240339f9 (patch)
tree267bdb72f0fad43779080cd1907dd8159a6c7154 /src/shader_recompiler/backend/spirv/emit_spirv.cpp
parentshader: Refactor half floating instructions (diff)
downloadyuzu-76c8a962ac4eae77e71d66a72c448930240339f9.tar
yuzu-76c8a962ac4eae77e71d66a72c448930240339f9.tar.gz
yuzu-76c8a962ac4eae77e71d66a72c448930240339f9.tar.bz2
yuzu-76c8a962ac4eae77e71d66a72c448930240339f9.tar.lz
yuzu-76c8a962ac4eae77e71d66a72c448930240339f9.tar.xz
yuzu-76c8a962ac4eae77e71d66a72c448930240339f9.tar.zst
yuzu-76c8a962ac4eae77e71d66a72c448930240339f9.zip
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp107
1 files changed, 60 insertions, 47 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index b8978b94a..efd0b70b7 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -113,6 +113,43 @@ Id TypeId(const EmitContext& ctx, IR::Type type) {
}
}
+Id DefineMain(EmitContext& ctx, IR::Program& program) {
+ const Id void_function{ctx.TypeFunction(ctx.void_id)};
+ const Id main{ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function)};
+ for (IR::Block* const block : program.blocks) {
+ ctx.AddLabel(block->Definition<Id>());
+ for (IR::Inst& inst : block->Instructions()) {
+ EmitInst(ctx, &inst);
+ }
+ }
+ ctx.OpFunctionEnd();
+ return main;
+}
+
+void DefineEntryPoint(Environment& env, EmitContext& ctx, Id main) {
+ const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
+ spv::ExecutionModel execution_model{};
+ switch (env.ShaderStage()) {
+ case Shader::Stage::Compute: {
+ const std::array<u32, 3> workgroup_size{env.WorkgroupSize()};
+ execution_model = spv::ExecutionModel::GLCompute;
+ ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0],
+ workgroup_size[1], workgroup_size[2]);
+ break;
+ }
+ case Shader::Stage::VertexB:
+ execution_model = spv::ExecutionModel::Vertex;
+ break;
+ case Shader::Stage::Fragment:
+ execution_model = spv::ExecutionModel::Fragment;
+ ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
+ break;
+ default:
+ throw NotImplementedException("Stage {}", env.ShaderStage());
+ }
+ ctx.AddEntryPoint(execution_model, main, "main", interfaces);
+}
+
void SetupDenormControl(const Profile& profile, const IR::Program& program, EmitContext& ctx,
Id main_func) {
if (!profile.support_float_controls) {
@@ -173,6 +210,25 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit
}
}
+void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ctx) {
+ if (info.uses_sampled_1d) {
+ ctx.AddCapability(spv::Capability::Sampled1D);
+ }
+ if (info.uses_sparse_residency) {
+ ctx.AddCapability(spv::Capability::SparseResidency);
+ }
+ if (info.uses_demote_to_helper_invocation) {
+ ctx.AddExtension("SPV_EXT_demote_to_helper_invocation");
+ ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
+ }
+ if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) {
+ ctx.AddExtension("SPV_KHR_shader_draw_parameters");
+ ctx.AddCapability(spv::Capability::DrawParameters);
+ }
+ // TODO: Track this usage
+ ctx.AddCapability(spv::Capability::ImageGatherExtended);
+}
+
Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) {
// Phi nodes can have forward declarations, if an argument is not defined provide a forward
// declaration of it. Invoke will take care of giving it the right definition when it's
@@ -202,53 +258,10 @@ Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) {
std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program,
u32& binding) {
EmitContext ctx{profile, program, binding};
- const Id void_function{ctx.TypeFunction(ctx.void_id)};
- const Id func{ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function)};
- for (IR::Block* const block : program.blocks) {
- ctx.AddLabel(block->Definition<Id>());
- for (IR::Inst& inst : block->Instructions()) {
- EmitInst(ctx, &inst);
- }
- }
- ctx.OpFunctionEnd();
-
- const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
- spv::ExecutionModel execution_model{};
- switch (env.ShaderStage()) {
- case Shader::Stage::Compute: {
- const std::array<u32, 3> workgroup_size{env.WorkgroupSize()};
- execution_model = spv::ExecutionModel::GLCompute;
- ctx.AddExecutionMode(func, spv::ExecutionMode::LocalSize, workgroup_size[0],
- workgroup_size[1], workgroup_size[2]);
- break;
- }
- case Shader::Stage::VertexB:
- execution_model = spv::ExecutionModel::Vertex;
- break;
- case Shader::Stage::Fragment:
- execution_model = spv::ExecutionModel::Fragment;
- ctx.AddExecutionMode(func, spv::ExecutionMode::OriginUpperLeft);
- break;
- default:
- throw NotImplementedException("Stage {}", env.ShaderStage());
- }
- ctx.AddEntryPoint(execution_model, func, "main", interfaces);
-
- SetupDenormControl(profile, program, ctx, func);
- const Info& info{program.info};
- if (info.uses_sampled_1d) {
- ctx.AddCapability(spv::Capability::Sampled1D);
- }
- if (info.uses_sparse_residency) {
- ctx.AddCapability(spv::Capability::SparseResidency);
- }
- if (info.uses_demote_to_helper_invocation) {
- ctx.AddExtension("SPV_EXT_demote_to_helper_invocation");
- ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
- }
- // TODO: Track this usage
- ctx.AddCapability(spv::Capability::ImageGatherExtended);
-
+ const Id main{DefineMain(ctx, program)};
+ DefineEntryPoint(env, ctx, main);
+ SetupDenormControl(profile, program, ctx, main);
+ SetupCapabilities(profile, program.info, ctx);
return ctx.Assemble();
}