diff options
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index f048174cb..b9fa5098c 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <climits> | 7 | #include <climits> |
| 8 | #include <string_view> | 8 | #include <string_view> |
| 9 | #include <queue> | ||
| 10 | 9 | ||
| 11 | #include <fmt/format.h> | 10 | #include <fmt/format.h> |
| 12 | 11 | ||
| @@ -430,6 +429,16 @@ Id DescType(EmitContext& ctx, Id sampled_type, Id pointer_type, u32 count) { | |||
| 430 | } | 429 | } |
| 431 | 430 | ||
| 432 | constexpr size_t NUM_FIXEDFNCTEXTURE = 10; | 431 | constexpr size_t NUM_FIXEDFNCTEXTURE = 10; |
| 432 | |||
| 433 | size_t FindFistUnUsedLocation(const auto& used_location) { | ||
| 434 | if (used_location.all()) { | ||
| 435 | throw RuntimeError("Unable to get an unused location"); | ||
| 436 | } | ||
| 437 | size_t location = 0; | ||
| 438 | while (location < used_location.size() && used_location.test(location)) | ||
| 439 | ++location; | ||
| 440 | return location; | ||
| 441 | } | ||
| 433 | } // Anonymous namespace | 442 | } // Anonymous namespace |
| 434 | 443 | ||
| 435 | void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) { | 444 | void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) { |
| @@ -1230,15 +1239,19 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1230 | loads[IR::Attribute::TessellationEvaluationPointV]) { | 1239 | loads[IR::Attribute::TessellationEvaluationPointV]) { |
| 1231 | tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); | 1240 | tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); |
| 1232 | } | 1241 | } |
| 1233 | std::queue<u32> ununsed_location; | 1242 | std::bitset<IR::NUM_GENERICS> used_location; |
| 1234 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | 1243 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { |
| 1235 | const AttributeType input_type{runtime_info.generic_input_types[index]}; | 1244 | const AttributeType input_type{runtime_info.generic_input_types[index]}; |
| 1236 | if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) || | 1245 | if (!runtime_info.previous_stage_stores.Generic(index)) { |
| 1237 | input_type == AttributeType::Disabled) { | ||
| 1238 | ununsed_location.push(static_cast<u32>(index)); | ||
| 1239 | continue; | 1246 | continue; |
| 1240 | } | 1247 | } |
| 1241 | 1248 | if (!loads.Generic(index)) { | |
| 1249 | continue; | ||
| 1250 | } | ||
| 1251 | if (input_type == AttributeType::Disabled) { | ||
| 1252 | continue; | ||
| 1253 | } | ||
| 1254 | used_location.set(index); | ||
| 1242 | const Id type{GetAttributeType(*this, input_type)}; | 1255 | const Id type{GetAttributeType(*this, input_type)}; |
| 1243 | const Id id{DefineInput(*this, type, true)}; | 1256 | const Id id{DefineInput(*this, type, true)}; |
| 1244 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); | 1257 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); |
| @@ -1265,22 +1278,16 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1265 | } | 1278 | } |
| 1266 | } | 1279 | } |
| 1267 | if (loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { | 1280 | if (loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { |
| 1268 | if (ununsed_location.empty()) { | 1281 | size_t location = FindFistUnUsedLocation(used_location); |
| 1269 | throw RuntimeError("Unable to get an unused location"); | 1282 | used_location.set(location); |
| 1270 | } | ||
| 1271 | u32 location = ununsed_location.front(); | ||
| 1272 | ununsed_location.pop(); | ||
| 1273 | const Id id{DefineInput(*this, F32[4], true)}; | 1283 | const Id id{DefineInput(*this, F32[4], true)}; |
| 1274 | Decorate(id, spv::Decoration::Location, location); | 1284 | Decorate(id, spv::Decoration::Location, location); |
| 1275 | input_front_color = id; | 1285 | input_front_color = id; |
| 1276 | } | 1286 | } |
| 1277 | for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { | 1287 | for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { |
| 1278 | if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { | 1288 | if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { |
| 1279 | if (ununsed_location.empty()) { | 1289 | size_t location = FindFistUnUsedLocation(used_location); |
| 1280 | throw RuntimeError("Unable to get an unused location"); | 1290 | used_location.set(location); |
| 1281 | } | ||
| 1282 | u32 location = ununsed_location.front(); | ||
| 1283 | ununsed_location.pop(); | ||
| 1284 | const Id id{DefineInput(*this, F32[4], true)}; | 1291 | const Id id{DefineInput(*this, F32[4], true)}; |
| 1285 | Decorate(id, spv::Decoration::Location, location); | 1292 | Decorate(id, spv::Decoration::Location, location); |
| 1286 | input_fixed_fnc_textures[index] = id; | 1293 | input_fixed_fnc_textures[index] = id; |
| @@ -1336,31 +1343,24 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | |||
| 1336 | viewport_mask = DefineOutput(*this, TypeArray(U32[1], Const(1u)), std::nullopt, | 1343 | viewport_mask = DefineOutput(*this, TypeArray(U32[1], Const(1u)), std::nullopt, |
| 1337 | spv::BuiltIn::ViewportMaskNV); | 1344 | spv::BuiltIn::ViewportMaskNV); |
| 1338 | } | 1345 | } |
| 1339 | std::queue<u32> ununsed_location; | 1346 | std::bitset<IR::NUM_GENERICS> used_location; |
| 1340 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | 1347 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { |
| 1341 | if (info.stores.Generic(index)) { | 1348 | if (info.stores.Generic(index)) { |
| 1342 | DefineGenericOutput(*this, index, invocations); | 1349 | DefineGenericOutput(*this, index, invocations); |
| 1343 | } else { | 1350 | used_location.set(index); |
| 1344 | ununsed_location.push(static_cast<u32>(index)); | ||
| 1345 | } | 1351 | } |
| 1346 | } | 1352 | } |
| 1347 | if (info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { | 1353 | if (info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { |
| 1348 | if (ununsed_location.empty()) { | 1354 | size_t location = FindFistUnUsedLocation(used_location); |
| 1349 | throw RuntimeError("Unable to get an unused location"); | 1355 | used_location.set(location); |
| 1350 | } | ||
| 1351 | u32 location = ununsed_location.front(); | ||
| 1352 | ununsed_location.pop(); | ||
| 1353 | const Id id{DefineOutput(*this, F32[4], invocations)}; | 1356 | const Id id{DefineOutput(*this, F32[4], invocations)}; |
| 1354 | Decorate(id, spv::Decoration::Location, location); | 1357 | Decorate(id, spv::Decoration::Location, static_cast<u32>(location)); |
| 1355 | output_front_color = id; | 1358 | output_front_color = id; |
| 1356 | } | 1359 | } |
| 1357 | for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { | 1360 | for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { |
| 1358 | if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { | 1361 | if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { |
| 1359 | if (ununsed_location.empty()) { | 1362 | size_t location = FindFistUnUsedLocation(used_location); |
| 1360 | throw RuntimeError("Unable to get an unused location"); | 1363 | used_location.set(location); |
| 1361 | } | ||
| 1362 | u32 location = ununsed_location.front(); | ||
| 1363 | ununsed_location.pop(); | ||
| 1364 | const Id id{DefineOutput(*this, F32[4], invocations)}; | 1364 | const Id id{DefineOutput(*this, F32[4], invocations)}; |
| 1365 | Decorate(id, spv::Decoration::Location, location); | 1365 | Decorate(id, spv::Decoration::Location, location); |
| 1366 | output_fixed_fnc_textures[index] = id; | 1366 | output_fixed_fnc_textures[index] = id; |