diff options
Diffstat (limited to 'src/shader_recompiler')
6 files changed, 30 insertions, 9 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 74c42233d..f96d5ae37 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -1050,8 +1050,15 @@ void EmitContext::DefineOutputs(const Info& info) { | |||
| 1050 | const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; | 1050 | const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; |
| 1051 | clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); | 1051 | clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); |
| 1052 | } | 1052 | } |
| 1053 | if (info.stores_layer && | ||
| 1054 | (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) { | ||
| 1055 | if (stage == Stage::Fragment) { | ||
| 1056 | throw NotImplementedException("Storing Layer in fragment stage"); | ||
| 1057 | } | ||
| 1058 | layer = DefineOutput(*this, U32[1], spv::BuiltIn::Layer); | ||
| 1059 | } | ||
| 1053 | if (info.stores_viewport_index && | 1060 | if (info.stores_viewport_index && |
| 1054 | (profile.support_viewport_index_layer_non_geometry || stage == Shader::Stage::Geometry)) { | 1061 | (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) { |
| 1055 | if (stage == Stage::Fragment) { | 1062 | if (stage == Stage::Fragment) { |
| 1056 | throw NotImplementedException("Storing ViewportIndex in fragment stage"); | 1063 | throw NotImplementedException("Storing ViewportIndex in fragment stage"); |
| 1057 | } | 1064 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index b27e5540c..1f0d8be77 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -157,6 +157,7 @@ public: | |||
| 157 | Id front_face{}; | 157 | Id front_face{}; |
| 158 | Id point_coord{}; | 158 | Id point_coord{}; |
| 159 | Id clip_distances{}; | 159 | Id clip_distances{}; |
| 160 | Id layer{}; | ||
| 160 | Id viewport_index{}; | 161 | Id viewport_index{}; |
| 161 | 162 | ||
| 162 | Id fswzadd_lut_a{}; | 163 | Id fswzadd_lut_a{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 444ba276f..3bf4c6a9e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -124,17 +124,17 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | |||
| 124 | const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size()); | 124 | const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size()); |
| 125 | spv::ExecutionModel execution_model{}; | 125 | spv::ExecutionModel execution_model{}; |
| 126 | switch (program.stage) { | 126 | switch (program.stage) { |
| 127 | case Shader::Stage::Compute: { | 127 | case Stage::Compute: { |
| 128 | const std::array<u32, 3> workgroup_size{program.workgroup_size}; | 128 | const std::array<u32, 3> workgroup_size{program.workgroup_size}; |
| 129 | execution_model = spv::ExecutionModel::GLCompute; | 129 | execution_model = spv::ExecutionModel::GLCompute; |
| 130 | ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0], | 130 | ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0], |
| 131 | workgroup_size[1], workgroup_size[2]); | 131 | workgroup_size[1], workgroup_size[2]); |
| 132 | break; | 132 | break; |
| 133 | } | 133 | } |
| 134 | case Shader::Stage::VertexB: | 134 | case Stage::VertexB: |
| 135 | execution_model = spv::ExecutionModel::Vertex; | 135 | execution_model = spv::ExecutionModel::Vertex; |
| 136 | break; | 136 | break; |
| 137 | case Shader::Stage::Geometry: | 137 | case Stage::Geometry: |
| 138 | execution_model = spv::ExecutionModel::Geometry; | 138 | execution_model = spv::ExecutionModel::Geometry; |
| 139 | ctx.AddCapability(spv::Capability::Geometry); | 139 | ctx.AddCapability(spv::Capability::Geometry); |
| 140 | ctx.AddCapability(spv::Capability::GeometryStreams); | 140 | ctx.AddCapability(spv::Capability::GeometryStreams); |
| @@ -172,7 +172,7 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | |||
| 172 | ctx.AddExecutionMode(main, spv::ExecutionMode::OutputVertices, program.output_vertices); | 172 | ctx.AddExecutionMode(main, spv::ExecutionMode::OutputVertices, program.output_vertices); |
| 173 | ctx.AddExecutionMode(main, spv::ExecutionMode::Invocations, program.invocations); | 173 | ctx.AddExecutionMode(main, spv::ExecutionMode::Invocations, program.invocations); |
| 174 | break; | 174 | break; |
| 175 | case Shader::Stage::Fragment: | 175 | case Stage::Fragment: |
| 176 | execution_model = spv::ExecutionModel::Fragment; | 176 | execution_model = spv::ExecutionModel::Fragment; |
| 177 | ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); | 177 | ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); |
| 178 | if (program.info.stores_frag_depth) { | 178 | if (program.info.stores_frag_depth) { |
| @@ -258,10 +258,14 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | |||
| 258 | ctx.AddExtension("SPV_EXT_demote_to_helper_invocation"); | 258 | ctx.AddExtension("SPV_EXT_demote_to_helper_invocation"); |
| 259 | ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); | 259 | ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); |
| 260 | } | 260 | } |
| 261 | if (info.stores_layer) { | ||
| 262 | ctx.AddCapability(spv::Capability::ShaderLayer); | ||
| 263 | } | ||
| 261 | if (info.stores_viewport_index) { | 264 | if (info.stores_viewport_index) { |
| 262 | ctx.AddCapability(spv::Capability::MultiViewport); | 265 | ctx.AddCapability(spv::Capability::MultiViewport); |
| 263 | if (profile.support_viewport_index_layer_non_geometry && | 266 | } |
| 264 | ctx.stage != Shader::Stage::Geometry) { | 267 | if (info.stores_layer || info.stores_viewport_index) { |
| 268 | if (profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { | ||
| 265 | ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); | 269 | ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); |
| 266 | ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | 270 | ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); |
| 267 | } | 271 | } |
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 f9c151a5c..59c56c5ba 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 | |||
| @@ -76,9 +76,14 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | |||
| 76 | const Id clip_num{ctx.Constant(ctx.U32[1], index)}; | 76 | const Id clip_num{ctx.Constant(ctx.U32[1], index)}; |
| 77 | return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); | 77 | return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); |
| 78 | } | 78 | } |
| 79 | case IR::Attribute::Layer: | ||
| 80 | return ctx.profile.support_viewport_index_layer_non_geometry || | ||
| 81 | ctx.stage == Shader::Stage::Geometry | ||
| 82 | ? std::optional<Id>{ctx.layer} | ||
| 83 | : std::nullopt; | ||
| 79 | case IR::Attribute::ViewportIndex: | 84 | case IR::Attribute::ViewportIndex: |
| 80 | return (ctx.profile.support_viewport_index_layer_non_geometry || | 85 | return ctx.profile.support_viewport_index_layer_non_geometry || |
| 81 | ctx.stage == Shader::Stage::Geometry) | 86 | ctx.stage == Shader::Stage::Geometry |
| 82 | ? std::optional<Id>{ctx.viewport_index} | 87 | ? std::optional<Id>{ctx.viewport_index} |
| 83 | : std::nullopt; | 88 | : std::nullopt; |
| 84 | default: | 89 | default: |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 116d93c1c..617ec05ce 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -83,6 +83,9 @@ void SetAttribute(Info& info, IR::Attribute attribute) { | |||
| 83 | case IR::Attribute::ClipDistance7: | 83 | case IR::Attribute::ClipDistance7: |
| 84 | info.stores_clip_distance = true; | 84 | info.stores_clip_distance = true; |
| 85 | break; | 85 | break; |
| 86 | case IR::Attribute::Layer: | ||
| 87 | info.stores_layer = true; | ||
| 88 | break; | ||
| 86 | case IR::Attribute::ViewportIndex: | 89 | case IR::Attribute::ViewportIndex: |
| 87 | info.stores_viewport_index = true; | 90 | info.stores_viewport_index = true; |
| 88 | break; | 91 | break; |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index 15cf09c3d..e078b0fa1 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -109,6 +109,7 @@ struct Info { | |||
| 109 | bool stores_position{}; | 109 | bool stores_position{}; |
| 110 | bool stores_point_size{}; | 110 | bool stores_point_size{}; |
| 111 | bool stores_clip_distance{}; | 111 | bool stores_clip_distance{}; |
| 112 | bool stores_layer{}; | ||
| 112 | bool stores_viewport_index{}; | 113 | bool stores_viewport_index{}; |
| 113 | bool stores_indexed_attributes{}; | 114 | bool stores_indexed_attributes{}; |
| 114 | 115 | ||