summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/shader/decode/texture.cpp8
-rw-r--r--src/video_core/shader/shader_ir.cpp120
-rw-r--r--src/video_core/shader/shader_ir.h2
3 files changed, 72 insertions, 58 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index f33e9c67c..d61e656b7 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -150,7 +150,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
150 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 150 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
151 } 151 }
152 152
153 WriteTexsInstructionFloat(bb, instr, values); 153 WriteTexsInstructionFloat(bb, instr, values, true);
154 break; 154 break;
155 } 155 }
156 case OpCode::Id::TXQ_B: 156 case OpCode::Id::TXQ_B:
@@ -374,14 +374,14 @@ void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const
374 } 374 }
375} 375}
376 376
377void ShaderIR::WriteTexsInstructionFloat(NodeBlock& bb, Instruction instr, 377void ShaderIR::WriteTexsInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components,
378 const Node4& components) { 378 bool ignore_mask) {
379 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle 379 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle
380 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 380 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
381 381
382 u32 dest_elem = 0; 382 u32 dest_elem = 0;
383 for (u32 component = 0; component < 4; ++component) { 383 for (u32 component = 0; component < 4; ++component) {
384 if (!instr.texs.IsComponentEnabled(component)) 384 if (!instr.texs.IsComponentEnabled(component) && !ignore_mask)
385 continue; 385 continue;
386 SetTemporary(bb, dest_elem++, components[component]); 386 SetTemporary(bb, dest_elem++, components[component]);
387 } 387 }
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 1d718ccc6..1d9825c76 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -2,8 +2,9 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
6#include <array>
5#include <cmath> 7#include <cmath>
6#include <unordered_map>
7 8
8#include "common/assert.h" 9#include "common/assert.h"
9#include "common/common_types.h" 10#include "common/common_types.h"
@@ -270,21 +271,24 @@ Node ShaderIR::GetSaturatedHalfFloat(Node value, bool saturate) {
270} 271}
271 272
272Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) { 273Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
273 const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { 274 static constexpr std::array comparison_table{
274 {PredCondition::LessThan, OperationCode::LogicalFLessThan}, 275 std::pair{PredCondition::LessThan, OperationCode::LogicalFLessThan},
275 {PredCondition::Equal, OperationCode::LogicalFEqual}, 276 std::pair{PredCondition::Equal, OperationCode::LogicalFEqual},
276 {PredCondition::LessEqual, OperationCode::LogicalFLessEqual}, 277 std::pair{PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
277 {PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan}, 278 std::pair{PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
278 {PredCondition::NotEqual, OperationCode::LogicalFNotEqual}, 279 std::pair{PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
279 {PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual}, 280 std::pair{PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
280 {PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan}, 281 std::pair{PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
281 {PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual}, 282 std::pair{PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
282 {PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual}, 283 std::pair{PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
283 {PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan}, 284 std::pair{PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
284 {PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}}; 285 std::pair{PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual},
285 286 };
286 const auto comparison{PredicateComparisonTable.find(condition)}; 287
287 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), 288 const auto comparison =
289 std::find_if(comparison_table.cbegin(), comparison_table.cend(),
290 [condition](const auto entry) { return condition == entry.first; });
291 UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
288 "Unknown predicate comparison operation"); 292 "Unknown predicate comparison operation");
289 293
290 Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b); 294 Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
@@ -305,21 +309,24 @@ Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, N
305 309
306Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a, 310Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
307 Node op_b) { 311 Node op_b) {
308 const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { 312 static constexpr std::array comparison_table{
309 {PredCondition::LessThan, OperationCode::LogicalILessThan}, 313 std::pair{PredCondition::LessThan, OperationCode::LogicalILessThan},
310 {PredCondition::Equal, OperationCode::LogicalIEqual}, 314 std::pair{PredCondition::Equal, OperationCode::LogicalIEqual},
311 {PredCondition::LessEqual, OperationCode::LogicalILessEqual}, 315 std::pair{PredCondition::LessEqual, OperationCode::LogicalILessEqual},
312 {PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan}, 316 std::pair{PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
313 {PredCondition::NotEqual, OperationCode::LogicalINotEqual}, 317 std::pair{PredCondition::NotEqual, OperationCode::LogicalINotEqual},
314 {PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual}, 318 std::pair{PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
315 {PredCondition::LessThanWithNan, OperationCode::LogicalILessThan}, 319 std::pair{PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
316 {PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual}, 320 std::pair{PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
317 {PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual}, 321 std::pair{PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
318 {PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan}, 322 std::pair{PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
319 {PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}}; 323 std::pair{PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual},
320 324 };
321 const auto comparison{PredicateComparisonTable.find(condition)}; 325
322 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), 326 const auto comparison =
327 std::find_if(comparison_table.cbegin(), comparison_table.cend(),
328 [condition](const auto entry) { return condition == entry.first; });
329 UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
323 "Unknown predicate comparison operation"); 330 "Unknown predicate comparison operation");
324 331
325 Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, std::move(op_a), 332 Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, std::move(op_a),
@@ -336,36 +343,43 @@ Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_si
336 343
337Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a, 344Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a,
338 Node op_b) { 345 Node op_b) {
339 const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { 346 static constexpr std::array comparison_table{
340 {PredCondition::LessThan, OperationCode::Logical2HLessThan}, 347 std::pair{PredCondition::LessThan, OperationCode::Logical2HLessThan},
341 {PredCondition::Equal, OperationCode::Logical2HEqual}, 348 std::pair{PredCondition::Equal, OperationCode::Logical2HEqual},
342 {PredCondition::LessEqual, OperationCode::Logical2HLessEqual}, 349 std::pair{PredCondition::LessEqual, OperationCode::Logical2HLessEqual},
343 {PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan}, 350 std::pair{PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan},
344 {PredCondition::NotEqual, OperationCode::Logical2HNotEqual}, 351 std::pair{PredCondition::NotEqual, OperationCode::Logical2HNotEqual},
345 {PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual}, 352 std::pair{PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual},
346 {PredCondition::LessThanWithNan, OperationCode::Logical2HLessThanWithNan}, 353 std::pair{PredCondition::LessThanWithNan, OperationCode::Logical2HLessThanWithNan},
347 {PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan}, 354 std::pair{PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan},
348 {PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan}, 355 std::pair{PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan},
349 {PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan}, 356 std::pair{PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan},
350 {PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan}}; 357 std::pair{PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan},
351 358 };
352 const auto comparison{PredicateComparisonTable.find(condition)}; 359
353 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), 360 const auto comparison =
361 std::find_if(comparison_table.cbegin(), comparison_table.cend(),
362 [condition](const auto entry) { return condition == entry.first; });
363 UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
354 "Unknown predicate comparison operation"); 364 "Unknown predicate comparison operation");
355 365
356 return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b)); 366 return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b));
357} 367}
358 368
359OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) { 369OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) {
360 const std::unordered_map<PredOperation, OperationCode> PredicateOperationTable = { 370 static constexpr std::array operation_table{
361 {PredOperation::And, OperationCode::LogicalAnd}, 371 OperationCode::LogicalAnd,
362 {PredOperation::Or, OperationCode::LogicalOr}, 372 OperationCode::LogicalOr,
363 {PredOperation::Xor, OperationCode::LogicalXor}, 373 OperationCode::LogicalXor,
364 }; 374 };
365 375
366 const auto op = PredicateOperationTable.find(operation); 376 const auto index = static_cast<std::size_t>(operation);
367 UNIMPLEMENTED_IF_MSG(op == PredicateOperationTable.end(), "Unknown predicate operation"); 377 if (index >= operation_table.size()) {
368 return op->second; 378 UNIMPLEMENTED_MSG("Unknown predicate operation.");
379 return {};
380 }
381
382 return operation_table[index];
369} 383}
370 384
371Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) const { 385Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) const {
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 3ebea91b9..1fd44bde1 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -329,7 +329,7 @@ private:
329 const Node4& components); 329 const Node4& components);
330 330
331 void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, 331 void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
332 const Node4& components); 332 const Node4& components, bool ignore_mask = false);
333 void WriteTexsInstructionHalfFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, 333 void WriteTexsInstructionHalfFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
334 const Node4& components); 334 const Node4& components);
335 335