diff options
Diffstat (limited to 'src/shader_recompiler')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 81c79e1ed..2809f9281 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <climits> | 7 | #include <climits> |
| 8 | #include <string_view> | 8 | #include <string_view> |
| 9 | #include <queue> | ||
| 9 | 10 | ||
| 10 | #include <fmt/format.h> | 11 | #include <fmt/format.h> |
| 11 | 12 | ||
| @@ -1201,18 +1202,6 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1201 | } | 1202 | } |
| 1202 | } | 1203 | } |
| 1203 | } | 1204 | } |
| 1204 | if (loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { | ||
| 1205 | const Id id{DefineInput(*this, F32[4], true)}; | ||
| 1206 | Decorate(id, spv::Decoration::Location, static_cast<u32>(11)); | ||
| 1207 | input_front_color = id; | ||
| 1208 | } | ||
| 1209 | for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) { | ||
| 1210 | if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { | ||
| 1211 | const Id id{DefineInput(*this, F32[4], true)}; | ||
| 1212 | Decorate(id, spv::Decoration::Location, static_cast<u32>(12)); | ||
| 1213 | input_fixed_fnc_textures[index] = id; | ||
| 1214 | } | ||
| 1215 | } | ||
| 1216 | if (loads[IR::Attribute::InstanceId]) { | 1205 | if (loads[IR::Attribute::InstanceId]) { |
| 1217 | if (profile.support_vertex_instance_id) { | 1206 | if (profile.support_vertex_instance_id) { |
| 1218 | instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId); | 1207 | instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId); |
| @@ -1239,17 +1228,15 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1239 | loads[IR::Attribute::TessellationEvaluationPointV]) { | 1228 | loads[IR::Attribute::TessellationEvaluationPointV]) { |
| 1240 | tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); | 1229 | tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); |
| 1241 | } | 1230 | } |
| 1231 | std::queue<u32> ununsed_location; | ||
| 1242 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | 1232 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { |
| 1243 | const AttributeType input_type{runtime_info.generic_input_types[index]}; | 1233 | const AttributeType input_type{runtime_info.generic_input_types[index]}; |
| 1244 | if (!runtime_info.previous_stage_stores.Generic(index)) { | 1234 | if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) || |
| 1245 | continue; | 1235 | input_type == AttributeType::Disabled) { |
| 1246 | } | 1236 | ununsed_location.push(static_cast<u32>(index)); |
| 1247 | if (!loads.Generic(index)) { | ||
| 1248 | continue; | ||
| 1249 | } | ||
| 1250 | if (input_type == AttributeType::Disabled) { | ||
| 1251 | continue; | 1237 | continue; |
| 1252 | } | 1238 | } |
| 1239 | |||
| 1253 | const Id type{GetAttributeType(*this, input_type)}; | 1240 | const Id type{GetAttributeType(*this, input_type)}; |
| 1254 | const Id id{DefineInput(*this, type, true)}; | 1241 | const Id id{DefineInput(*this, type, true)}; |
| 1255 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); | 1242 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); |
| @@ -1275,6 +1262,28 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1275 | break; | 1262 | break; |
| 1276 | } | 1263 | } |
| 1277 | } | 1264 | } |
| 1265 | if (loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { | ||
| 1266 | if (ununsed_location.empty()) { | ||
| 1267 | throw RuntimeError("Unable to get an unused location"); | ||
| 1268 | } | ||
| 1269 | u32 location = ununsed_location.front(); | ||
| 1270 | ununsed_location.pop(); | ||
| 1271 | const Id id{DefineInput(*this, F32[4], true)}; | ||
| 1272 | Decorate(id, spv::Decoration::Location, location); | ||
| 1273 | input_front_color = id; | ||
| 1274 | } | ||
| 1275 | for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) { | ||
| 1276 | if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { | ||
| 1277 | if (ununsed_location.empty()) { | ||
| 1278 | throw RuntimeError("Unable to get an unused location"); | ||
| 1279 | } | ||
| 1280 | u32 location = ununsed_location.front(); | ||
| 1281 | ununsed_location.pop(); | ||
| 1282 | const Id id{DefineInput(*this, F32[4], true)}; | ||
| 1283 | Decorate(id, spv::Decoration::Location, location); | ||
| 1284 | input_fixed_fnc_textures[index] = id; | ||
| 1285 | } | ||
| 1286 | } | ||
| 1278 | if (stage == Stage::TessellationEval) { | 1287 | if (stage == Stage::TessellationEval) { |
| 1279 | for (size_t index = 0; index < info.uses_patches.size(); ++index) { | 1288 | for (size_t index = 0; index < info.uses_patches.size(); ++index) { |
| 1280 | if (!info.uses_patches[index]) { | 1289 | if (!info.uses_patches[index]) { |
| @@ -1325,23 +1334,36 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | |||
| 1325 | viewport_mask = DefineOutput(*this, TypeArray(U32[1], Const(1u)), std::nullopt, | 1334 | viewport_mask = DefineOutput(*this, TypeArray(U32[1], Const(1u)), std::nullopt, |
| 1326 | spv::BuiltIn::ViewportMaskNV); | 1335 | spv::BuiltIn::ViewportMaskNV); |
| 1327 | } | 1336 | } |
| 1328 | if (info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR) || stage == Stage::VertexB) { | 1337 | std::queue<u32> ununsed_location; |
| 1338 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | ||
| 1339 | if (info.stores.Generic(index)) { | ||
| 1340 | DefineGenericOutput(*this, index, invocations); | ||
| 1341 | } else { | ||
| 1342 | ununsed_location.push(static_cast<u32>(index)); | ||
| 1343 | } | ||
| 1344 | } | ||
| 1345 | if (info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { | ||
| 1346 | if (ununsed_location.empty()) { | ||
| 1347 | throw RuntimeError("Unable to get an unused location"); | ||
| 1348 | } | ||
| 1349 | u32 location = ununsed_location.front(); | ||
| 1350 | ununsed_location.pop(); | ||
| 1329 | const Id id{DefineOutput(*this, F32[4], invocations)}; | 1351 | const Id id{DefineOutput(*this, F32[4], invocations)}; |
| 1330 | Decorate(id, spv::Decoration::Location, static_cast<u32>(11)); | 1352 | Decorate(id, spv::Decoration::Location, location); |
| 1331 | output_front_color = id; | 1353 | output_front_color = id; |
| 1332 | } | 1354 | } |
| 1333 | for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) { | 1355 | for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) { |
| 1334 | if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { | 1356 | if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { |
| 1357 | if (ununsed_location.empty()) { | ||
| 1358 | throw RuntimeError("Unable to get an unused location"); | ||
| 1359 | } | ||
| 1360 | u32 location = ununsed_location.front(); | ||
| 1361 | ununsed_location.pop(); | ||
| 1335 | const Id id{DefineOutput(*this, F32[4], invocations)}; | 1362 | const Id id{DefineOutput(*this, F32[4], invocations)}; |
| 1336 | Decorate(id, spv::Decoration::Location, static_cast<u32>(12)); | 1363 | Decorate(id, spv::Decoration::Location, location); |
| 1337 | output_fixed_fnc_textures[index] = id; | 1364 | output_fixed_fnc_textures[index] = id; |
| 1338 | } | 1365 | } |
| 1339 | } | 1366 | } |
| 1340 | for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | ||
| 1341 | if (info.stores.Generic(index)) { | ||
| 1342 | DefineGenericOutput(*this, index, invocations); | ||
| 1343 | } | ||
| 1344 | } | ||
| 1345 | switch (stage) { | 1367 | switch (stage) { |
| 1346 | case Stage::TessellationControl: | 1368 | case Stage::TessellationControl: |
| 1347 | if (info.stores_tess_level_outer) { | 1369 | if (info.stores_tess_level_outer) { |