summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend')
-rw-r--r--src/shader_recompiler/frontend/ir/attribute.h6
-rw-r--r--src/shader_recompiler/frontend/ir/program.h1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp18
3 files changed, 17 insertions, 8 deletions
diff --git a/src/shader_recompiler/frontend/ir/attribute.h b/src/shader_recompiler/frontend/ir/attribute.h
index 8bf2ddf30..ca1199494 100644
--- a/src/shader_recompiler/frontend/ir/attribute.h
+++ b/src/shader_recompiler/frontend/ir/attribute.h
@@ -222,6 +222,8 @@ enum class Attribute : u64 {
222 FrontFace = 255, 222 FrontFace = 255,
223}; 223};
224 224
225constexpr size_t NUM_GENERICS = 32;
226
225[[nodiscard]] bool IsGeneric(Attribute attribute) noexcept; 227[[nodiscard]] bool IsGeneric(Attribute attribute) noexcept;
226 228
227[[nodiscard]] u32 GenericAttributeIndex(Attribute attribute); 229[[nodiscard]] u32 GenericAttributeIndex(Attribute attribute);
@@ -230,6 +232,10 @@ enum class Attribute : u64 {
230 232
231[[nodiscard]] std::string NameOf(Attribute attribute); 233[[nodiscard]] std::string NameOf(Attribute attribute);
232 234
235[[nodiscard]] constexpr IR::Attribute operator+(IR::Attribute attribute, size_t value) noexcept {
236 return static_cast<IR::Attribute>(static_cast<size_t>(attribute) + value);
237}
238
233} // namespace Shader::IR 239} // namespace Shader::IR
234 240
235template <> 241template <>
diff --git a/src/shader_recompiler/frontend/ir/program.h b/src/shader_recompiler/frontend/ir/program.h
index 9ede5b48d..ebcaa8bc2 100644
--- a/src/shader_recompiler/frontend/ir/program.h
+++ b/src/shader_recompiler/frontend/ir/program.h
@@ -27,6 +27,7 @@ struct Program {
27 u32 invocations{}; 27 u32 invocations{};
28 u32 local_memory_size{}; 28 u32 local_memory_size{};
29 u32 shared_memory_size{}; 29 u32 shared_memory_size{};
30 bool is_geometry_passthrough{};
30}; 31};
31 32
32[[nodiscard]] std::string DumpProgram(const Program& program); 33[[nodiscard]] std::string DumpProgram(const Program& program);
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index a8b727f1a..6b4b0ce5b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -46,7 +46,7 @@ void CollectInterpolationInfo(Environment& env, IR::Program& program) {
46 return; 46 return;
47 } 47 }
48 const ProgramHeader& sph{env.SPH()}; 48 const ProgramHeader& sph{env.SPH()};
49 for (size_t index = 0; index < program.info.input_generics.size(); ++index) { 49 for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
50 std::optional<PixelImap> imap; 50 std::optional<PixelImap> imap;
51 for (const PixelImap value : sph.ps.GenericInputMap(static_cast<u32>(index))) { 51 for (const PixelImap value : sph.ps.GenericInputMap(static_cast<u32>(index))) {
52 if (value == PixelImap::Unused) { 52 if (value == PixelImap::Unused) {
@@ -60,7 +60,7 @@ void CollectInterpolationInfo(Environment& env, IR::Program& program) {
60 if (!imap) { 60 if (!imap) {
61 continue; 61 continue;
62 } 62 }
63 program.info.input_generics[index].interpolation = [&] { 63 program.info.interpolation[index] = [&] {
64 switch (*imap) { 64 switch (*imap) {
65 case PixelImap::Unused: 65 case PixelImap::Unused:
66 case PixelImap::Perspective: 66 case PixelImap::Perspective:
@@ -140,6 +140,11 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
140 program.output_topology = sph.common3.output_topology; 140 program.output_topology = sph.common3.output_topology;
141 program.output_vertices = sph.common4.max_output_vertices; 141 program.output_vertices = sph.common4.max_output_vertices;
142 program.invocations = sph.common2.threads_per_input_primitive; 142 program.invocations = sph.common2.threads_per_input_primitive;
143 program.is_geometry_passthrough = sph.common0.geometry_passthrough != 0;
144 if (program.is_geometry_passthrough) {
145 const auto mask{env.GpPassthroughMask()};
146 program.info.passthrough.mask |= ~Common::BitCast<std::bitset<256>>(mask);
147 }
143 break; 148 break;
144 } 149 }
145 case Stage::Compute: 150 case Stage::Compute:
@@ -194,12 +199,9 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b
194 result.stage = Stage::VertexB; 199 result.stage = Stage::VertexB;
195 result.info = vertex_a.info; 200 result.info = vertex_a.info;
196 result.local_memory_size = std::max(vertex_a.local_memory_size, vertex_b.local_memory_size); 201 result.local_memory_size = std::max(vertex_a.local_memory_size, vertex_b.local_memory_size);
197 for (size_t index = 0; index < 32; ++index) { 202 result.info.loads.mask |= vertex_b.info.loads.mask;
198 result.info.input_generics[index].used |= vertex_b.info.input_generics[index].used; 203 result.info.stores.mask |= vertex_b.info.stores.mask;
199 if (vertex_b.info.stores_generics[index]) { 204
200 result.info.stores_generics[index] = true;
201 }
202 }
203 Optimization::JoinTextureInfo(result.info, vertex_b.info); 205 Optimization::JoinTextureInfo(result.info, vertex_b.info);
204 Optimization::JoinStorageInfo(result.info, vertex_b.info); 206 Optimization::JoinStorageInfo(result.info, vertex_b.info);
205 Optimization::DeadCodeEliminationPass(result); 207 Optimization::DeadCodeEliminationPass(result);