diff options
| author | 2021-05-21 02:12:32 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:33 -0400 | |
| commit | 9e7b6622c25aa858b96bf0f1c7f94223a2f449a2 (patch) | |
| tree | 48c62889aeb79d6f0f01a467ba0d1ac01dec512b /src/shader_recompiler/backend/spirv | |
| parent | emit_glasm_context_get_and_set.cpp: Add missing semicolons (diff) | |
| download | yuzu-9e7b6622c25aa858b96bf0f1c7f94223a2f449a2.tar.gz yuzu-9e7b6622c25aa858b96bf0f1c7f94223a2f449a2.tar.xz yuzu-9e7b6622c25aa858b96bf0f1c7f94223a2f449a2.zip | |
shader: Split profile and runtime information in separate structs
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
6 files changed, 42 insertions, 33 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index a98e08392..3e8899f53 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -136,7 +136,7 @@ Id DefineInput(EmitContext& ctx, Id type, bool per_invocation, | |||
| 136 | break; | 136 | break; |
| 137 | case Stage::Geometry: | 137 | case Stage::Geometry: |
| 138 | if (per_invocation) { | 138 | if (per_invocation) { |
| 139 | const u32 num_vertices{NumVertices(ctx.profile.input_topology)}; | 139 | const u32 num_vertices{NumVertices(ctx.runtime_info.input_topology)}; |
| 140 | type = ctx.TypeArray(type, ctx.Const(num_vertices)); | 140 | type = ctx.TypeArray(type, ctx.Const(num_vertices)); |
| 141 | } | 141 | } |
| 142 | break; | 142 | break; |
| @@ -161,8 +161,8 @@ void DefineGenericOutput(EmitContext& ctx, size_t index, std::optional<u32> invo | |||
| 161 | while (element < 4) { | 161 | while (element < 4) { |
| 162 | const u32 remainder{4 - element}; | 162 | const u32 remainder{4 - element}; |
| 163 | const TransformFeedbackVarying* xfb_varying{}; | 163 | const TransformFeedbackVarying* xfb_varying{}; |
| 164 | if (!ctx.profile.xfb_varyings.empty()) { | 164 | if (!ctx.runtime_info.xfb_varyings.empty()) { |
| 165 | xfb_varying = &ctx.profile.xfb_varyings[base_attr_index + element]; | 165 | xfb_varying = &ctx.runtime_info.xfb_varyings[base_attr_index + element]; |
| 166 | xfb_varying = xfb_varying && xfb_varying->components > 0 ? xfb_varying : nullptr; | 166 | xfb_varying = xfb_varying && xfb_varying->components > 0 ? xfb_varying : nullptr; |
| 167 | } | 167 | } |
| 168 | const u32 num_components{xfb_varying ? xfb_varying->components : remainder}; | 168 | const u32 num_components{xfb_varying ? xfb_varying->components : remainder}; |
| @@ -208,7 +208,7 @@ Id GetAttributeType(EmitContext& ctx, AttributeType type) { | |||
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { | 210 | std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { |
| 211 | const AttributeType type{ctx.profile.generic_input_types.at(index)}; | 211 | const AttributeType type{ctx.runtime_info.generic_input_types.at(index)}; |
| 212 | switch (type) { | 212 | switch (type) { |
| 213 | case AttributeType::Float: | 213 | case AttributeType::Float: |
| 214 | return AttrInfo{ctx.input_f32, ctx.F32[1], false}; | 214 | return AttrInfo{ctx.input_f32, ctx.F32[1], false}; |
| @@ -441,13 +441,15 @@ void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_vie | |||
| 441 | } | 441 | } |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | EmitContext::EmitContext(const Profile& profile_, IR::Program& program, Bindings& binding) | 444 | EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_info_, |
| 445 | : Sirit::Module(profile_.supported_spirv), profile{profile_}, stage{program.stage} { | 445 | IR::Program& program, Bindings& bindings) |
| 446 | : Sirit::Module(profile_.supported_spirv), profile{profile_}, | ||
| 447 | runtime_info{runtime_info_}, stage{program.stage} { | ||
| 446 | const bool is_unified{profile.unified_descriptor_binding}; | 448 | const bool is_unified{profile.unified_descriptor_binding}; |
| 447 | u32& uniform_binding{is_unified ? binding.unified : binding.uniform_buffer}; | 449 | u32& uniform_binding{is_unified ? bindings.unified : bindings.uniform_buffer}; |
| 448 | u32& storage_binding{is_unified ? binding.unified : binding.storage_buffer}; | 450 | u32& storage_binding{is_unified ? bindings.unified : bindings.storage_buffer}; |
| 449 | u32& texture_binding{is_unified ? binding.unified : binding.texture}; | 451 | u32& texture_binding{is_unified ? bindings.unified : bindings.texture}; |
| 450 | u32& image_binding{is_unified ? binding.unified : binding.image}; | 452 | u32& image_binding{is_unified ? bindings.unified : bindings.image}; |
| 451 | AddCapability(spv::Capability::Shader); | 453 | AddCapability(spv::Capability::Shader); |
| 452 | DefineCommonTypes(program.info); | 454 | DefineCommonTypes(program.info); |
| 453 | DefineCommonConstants(); | 455 | DefineCommonConstants(); |
| @@ -1211,7 +1213,7 @@ void EmitContext::DefineInputs(const Info& info) { | |||
| 1211 | if (!generic.used) { | 1213 | if (!generic.used) { |
| 1212 | continue; | 1214 | continue; |
| 1213 | } | 1215 | } |
| 1214 | const AttributeType input_type{profile.generic_input_types[index]}; | 1216 | const AttributeType input_type{runtime_info.generic_input_types[index]}; |
| 1215 | if (input_type == AttributeType::Disabled) { | 1217 | if (input_type == AttributeType::Disabled) { |
| 1216 | continue; | 1218 | continue; |
| 1217 | } | 1219 | } |
| @@ -1256,7 +1258,7 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | |||
| 1256 | if (info.stores_position || stage == Stage::VertexB) { | 1258 | if (info.stores_position || stage == Stage::VertexB) { |
| 1257 | output_position = DefineOutput(*this, F32[4], invocations, spv::BuiltIn::Position); | 1259 | output_position = DefineOutput(*this, F32[4], invocations, spv::BuiltIn::Position); |
| 1258 | } | 1260 | } |
| 1259 | if (info.stores_point_size || profile.fixed_state_point_size) { | 1261 | if (info.stores_point_size || runtime_info.fixed_state_point_size) { |
| 1260 | if (stage == Stage::Fragment) { | 1262 | if (stage == Stage::Fragment) { |
| 1261 | throw NotImplementedException("Storing PointSize in fragment stage"); | 1263 | throw NotImplementedException("Storing PointSize in fragment stage"); |
| 1262 | } | 1264 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index d2b79f6c1..961c9180c 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -103,7 +103,8 @@ struct GenericElementInfo { | |||
| 103 | 103 | ||
| 104 | class EmitContext final : public Sirit::Module { | 104 | class EmitContext final : public Sirit::Module { |
| 105 | public: | 105 | public: |
| 106 | explicit EmitContext(const Profile& profile, IR::Program& program, Bindings& binding); | 106 | explicit EmitContext(const Profile& profile, const RuntimeInfo& runtime_info, |
| 107 | IR::Program& program, Bindings& binding); | ||
| 107 | ~EmitContext(); | 108 | ~EmitContext(); |
| 108 | 109 | ||
| 109 | [[nodiscard]] Id Def(const IR::Value& value); | 110 | [[nodiscard]] Id Def(const IR::Value& value); |
| @@ -150,6 +151,7 @@ public: | |||
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | const Profile& profile; | 153 | const Profile& profile; |
| 154 | const RuntimeInfo& runtime_info; | ||
| 153 | Stage stage{}; | 155 | Stage stage{}; |
| 154 | 156 | ||
| 155 | Id void_id{}; | 157 | Id void_id{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 3e20ac3b9..cba420cda 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -226,16 +226,17 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | |||
| 226 | case Stage::TessellationEval: | 226 | case Stage::TessellationEval: |
| 227 | execution_model = spv::ExecutionModel::TessellationEvaluation; | 227 | execution_model = spv::ExecutionModel::TessellationEvaluation; |
| 228 | ctx.AddCapability(spv::Capability::Tessellation); | 228 | ctx.AddCapability(spv::Capability::Tessellation); |
| 229 | ctx.AddExecutionMode(main, ExecutionMode(ctx.profile.tess_primitive)); | 229 | ctx.AddExecutionMode(main, ExecutionMode(ctx.runtime_info.tess_primitive)); |
| 230 | ctx.AddExecutionMode(main, ExecutionMode(ctx.profile.tess_spacing)); | 230 | ctx.AddExecutionMode(main, ExecutionMode(ctx.runtime_info.tess_spacing)); |
| 231 | ctx.AddExecutionMode(main, ctx.profile.tess_clockwise ? spv::ExecutionMode::VertexOrderCw | 231 | ctx.AddExecutionMode(main, ctx.runtime_info.tess_clockwise |
| 232 | : spv::ExecutionMode::VertexOrderCcw); | 232 | ? spv::ExecutionMode::VertexOrderCw |
| 233 | : spv::ExecutionMode::VertexOrderCcw); | ||
| 233 | break; | 234 | break; |
| 234 | case Stage::Geometry: | 235 | case Stage::Geometry: |
| 235 | execution_model = spv::ExecutionModel::Geometry; | 236 | execution_model = spv::ExecutionModel::Geometry; |
| 236 | ctx.AddCapability(spv::Capability::Geometry); | 237 | ctx.AddCapability(spv::Capability::Geometry); |
| 237 | ctx.AddCapability(spv::Capability::GeometryStreams); | 238 | ctx.AddCapability(spv::Capability::GeometryStreams); |
| 238 | switch (ctx.profile.input_topology) { | 239 | switch (ctx.runtime_info.input_topology) { |
| 239 | case InputTopology::Points: | 240 | case InputTopology::Points: |
| 240 | ctx.AddExecutionMode(main, spv::ExecutionMode::InputPoints); | 241 | ctx.AddExecutionMode(main, spv::ExecutionMode::InputPoints); |
| 241 | break; | 242 | break; |
| @@ -279,7 +280,7 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | |||
| 279 | if (program.info.stores_frag_depth) { | 280 | if (program.info.stores_frag_depth) { |
| 280 | ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); | 281 | ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); |
| 281 | } | 282 | } |
| 282 | if (ctx.profile.force_early_z) { | 283 | if (ctx.runtime_info.force_early_z) { |
| 283 | ctx.AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests); | 284 | ctx.AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests); |
| 284 | } | 285 | } |
| 285 | break; | 286 | break; |
| @@ -402,7 +403,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | |||
| 402 | if (info.uses_sample_id) { | 403 | if (info.uses_sample_id) { |
| 403 | ctx.AddCapability(spv::Capability::SampleRateShading); | 404 | ctx.AddCapability(spv::Capability::SampleRateShading); |
| 404 | } | 405 | } |
| 405 | if (!ctx.profile.xfb_varyings.empty()) { | 406 | if (!ctx.runtime_info.xfb_varyings.empty()) { |
| 406 | ctx.AddCapability(spv::Capability::TransformFeedback); | 407 | ctx.AddCapability(spv::Capability::TransformFeedback); |
| 407 | } | 408 | } |
| 408 | if (info.uses_derivatives) { | 409 | if (info.uses_derivatives) { |
| @@ -433,8 +434,9 @@ void PatchPhiNodes(IR::Program& program, EmitContext& ctx) { | |||
| 433 | } | 434 | } |
| 434 | } // Anonymous namespace | 435 | } // Anonymous namespace |
| 435 | 436 | ||
| 436 | std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program, Bindings& binding) { | 437 | std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, |
| 437 | EmitContext ctx{profile, program, binding}; | 438 | IR::Program& program, Bindings& bindings) { |
| 439 | EmitContext ctx{profile, runtime_info, program, bindings}; | ||
| 438 | const Id main{DefineMain(ctx, program)}; | 440 | const Id main{DefineMain(ctx, program)}; |
| 439 | DefineEntryPoint(program, ctx, main); | 441 | DefineEntryPoint(program, ctx, main); |
| 440 | if (profile.support_float_controls) { | 442 | if (profile.support_float_controls) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index d8ab2d8ed..db0c935fe 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -16,12 +16,12 @@ | |||
| 16 | 16 | ||
| 17 | namespace Shader::Backend::SPIRV { | 17 | namespace Shader::Backend::SPIRV { |
| 18 | 18 | ||
| 19 | [[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program, | 19 | [[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, |
| 20 | Bindings& binding); | 20 | IR::Program& program, Bindings& bindings); |
| 21 | 21 | ||
| 22 | [[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program) { | 22 | [[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program) { |
| 23 | Bindings binding; | 23 | Bindings binding; |
| 24 | return EmitSPIRV(profile, program, binding); | 24 | return EmitSPIRV(profile, {}, program, binding); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | } // namespace Shader::Backend::SPIRV | 27 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 8e57ff070..c1b69c234 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -17,7 +17,7 @@ struct AttrInfo { | |||
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { | 19 | std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { |
| 20 | const AttributeType type{ctx.profile.generic_input_types.at(index)}; | 20 | const AttributeType type{ctx.runtime_info.generic_input_types.at(index)}; |
| 21 | switch (type) { | 21 | switch (type) { |
| 22 | case AttributeType::Float: | 22 | case AttributeType::Float: |
| 23 | return AttrInfo{ctx.input_f32, ctx.F32[1], false}; | 23 | return AttrInfo{ctx.input_f32, ctx.F32[1], false}; |
| @@ -468,7 +468,7 @@ Id EmitIsHelperInvocation(EmitContext& ctx) { | |||
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | Id EmitYDirection(EmitContext& ctx) { | 470 | Id EmitYDirection(EmitContext& ctx) { |
| 471 | return ctx.Const(ctx.profile.y_negate ? -1.0f : 1.0f); | 471 | return ctx.Const(ctx.runtime_info.y_negate ? -1.0f : 1.0f); |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { | 474 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index ba948f3c9..072a3b1bd 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp | |||
| @@ -18,8 +18,8 @@ void ConvertDepthMode(EmitContext& ctx) { | |||
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void SetFixedPipelinePointSize(EmitContext& ctx) { | 20 | void SetFixedPipelinePointSize(EmitContext& ctx) { |
| 21 | if (ctx.profile.fixed_state_point_size) { | 21 | if (ctx.runtime_info.fixed_state_point_size) { |
| 22 | const float point_size{*ctx.profile.fixed_state_point_size}; | 22 | const float point_size{*ctx.runtime_info.fixed_state_point_size}; |
| 23 | ctx.OpStore(ctx.output_point_size, ctx.Const(point_size)); | 23 | ctx.OpStore(ctx.output_point_size, ctx.Const(point_size)); |
| 24 | } | 24 | } |
| 25 | } | 25 | } |
| @@ -62,7 +62,10 @@ Id ComparisonFunction(EmitContext& ctx, CompareFunction comparison, Id operand_1 | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | void AlphaTest(EmitContext& ctx) { | 64 | void AlphaTest(EmitContext& ctx) { |
| 65 | const auto comparison{*ctx.profile.alpha_test_func}; | 65 | if (!ctx.runtime_info.alpha_test_func) { |
| 66 | return; | ||
| 67 | } | ||
| 68 | const auto comparison{*ctx.runtime_info.alpha_test_func}; | ||
| 66 | if (comparison == CompareFunction::Always) { | 69 | if (comparison == CompareFunction::Always) { |
| 67 | return; | 70 | return; |
| 68 | } | 71 | } |
| @@ -76,7 +79,7 @@ void AlphaTest(EmitContext& ctx) { | |||
| 76 | 79 | ||
| 77 | const Id true_label{ctx.OpLabel()}; | 80 | const Id true_label{ctx.OpLabel()}; |
| 78 | const Id discard_label{ctx.OpLabel()}; | 81 | const Id discard_label{ctx.OpLabel()}; |
| 79 | const Id alpha_reference{ctx.Const(ctx.profile.alpha_test_reference)}; | 82 | const Id alpha_reference{ctx.Const(ctx.runtime_info.alpha_test_reference)}; |
| 80 | const Id condition{ComparisonFunction(ctx, comparison, alpha, alpha_reference)}; | 83 | const Id condition{ComparisonFunction(ctx, comparison, alpha, alpha_reference)}; |
| 81 | 84 | ||
| 82 | ctx.OpSelectionMerge(true_label, spv::SelectionControlMask::MaskNone); | 85 | ctx.OpSelectionMerge(true_label, spv::SelectionControlMask::MaskNone); |
| @@ -113,7 +116,7 @@ void EmitPrologue(EmitContext& ctx) { | |||
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | void EmitEpilogue(EmitContext& ctx) { | 118 | void EmitEpilogue(EmitContext& ctx) { |
| 116 | if (ctx.stage == Stage::VertexB && ctx.profile.convert_depth_mode) { | 119 | if (ctx.stage == Stage::VertexB && ctx.runtime_info.convert_depth_mode) { |
| 117 | ConvertDepthMode(ctx); | 120 | ConvertDepthMode(ctx); |
| 118 | } | 121 | } |
| 119 | if (ctx.stage == Stage::Fragment) { | 122 | if (ctx.stage == Stage::Fragment) { |
| @@ -122,7 +125,7 @@ void EmitEpilogue(EmitContext& ctx) { | |||
| 122 | } | 125 | } |
| 123 | 126 | ||
| 124 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | 127 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { |
| 125 | if (ctx.profile.convert_depth_mode) { | 128 | if (ctx.runtime_info.convert_depth_mode) { |
| 126 | ConvertDepthMode(ctx); | 129 | ConvertDepthMode(ctx); |
| 127 | } | 130 | } |
| 128 | if (stream.IsImmediate()) { | 131 | if (stream.IsImmediate()) { |