summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp412
1 files changed, 411 insertions, 1 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 5f174bb7f..e4c3e3d9c 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -30,6 +30,7 @@ using namespace VideoCommon::Shader;
30 30
31using Maxwell = Tegra::Engines::Maxwell3D::Regs; 31using Maxwell = Tegra::Engines::Maxwell3D::Regs;
32using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage; 32using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage;
33using Operation = const OperationNode&;
33 34
34// TODO(Rodrigo): Use rasterizer's value 35// TODO(Rodrigo): Use rasterizer's value
35constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 0x1000; 36constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 0x1000;
@@ -73,6 +74,19 @@ constexpr u32 GetGenericAttributeLocation(Attribute::Index attribute) {
73 return static_cast<u32>(attribute) - static_cast<u32>(Attribute::Index::Attribute_0); 74 return static_cast<u32>(attribute) - static_cast<u32>(Attribute::Index::Attribute_0);
74} 75}
75 76
77/// Returns true if an object has to be treated as precise
78bool IsPrecise(Operation operand) {
79 const auto& meta = operand.GetMeta();
80
81 if (std::holds_alternative<MetaArithmetic>(meta)) {
82 return std::get<MetaArithmetic>(meta).precise;
83 }
84 if (std::holds_alternative<MetaHalfArithmetic>(meta)) {
85 return std::get<MetaHalfArithmetic>(meta).precise;
86 }
87 return false;
88}
89
76} // namespace 90} // namespace
77 91
78class SPIRVDecompiler : public Sirit::Module { 92class SPIRVDecompiler : public Sirit::Module {
@@ -194,6 +208,10 @@ public:
194 } 208 }
195 209
196private: 210private:
211 using OperationDecompilerFn = Id (SPIRVDecompiler::*)(Operation);
212 using OperationDecompilersArray =
213 std::array<OperationDecompilerFn, static_cast<std::size_t>(OperationCode::Amount)>;
214
197 static constexpr auto INTERNAL_FLAGS_COUNT = static_cast<std::size_t>(InternalFlag::Amount); 215 static constexpr auto INTERNAL_FLAGS_COUNT = static_cast<std::size_t>(InternalFlag::Amount);
198 static constexpr u32 CBUF_STRIDE = 16; 216 static constexpr u32 CBUF_STRIDE = 16;
199 217
@@ -468,7 +486,12 @@ private:
468 486
469 Id Visit(Node node) { 487 Id Visit(Node node) {
470 if (const auto operation = std::get_if<OperationNode>(node)) { 488 if (const auto operation = std::get_if<OperationNode>(node)) {
471 UNIMPLEMENTED(); 489 const auto operation_index = static_cast<std::size_t>(operation->GetCode());
490 const auto decompiler = operation_decompilers[operation_index];
491 if (decompiler == nullptr) {
492 UNREACHABLE_MSG("Operation decompiler {} not defined", operation_index);
493 }
494 return (this->*decompiler)(*operation);
472 495
473 } else if (const auto gpr = std::get_if<GprNode>(node)) { 496 } else if (const auto gpr = std::get_if<GprNode>(node)) {
474 UNIMPLEMENTED(); 497 UNIMPLEMENTED();
@@ -500,6 +523,184 @@ private:
500 return {}; 523 return {};
501 } 524 }
502 525
526 template <Id (Module::*func)(Id, Id), Type result_type, Type type_a = result_type>
527 Id Unary(Operation operation) {
528 const Id type_def = GetTypeDefinition(result_type);
529 const Id op_a = VisitOperand<type_a>(operation, 0);
530
531 const Id value = BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a)));
532 if (IsPrecise(operation)) {
533 Decorate(value, spv::Decoration::NoContraction);
534 }
535 return value;
536 }
537
538 template <Id (Module::*func)(Id, Id, Id), Type result_type, Type type_a = result_type,
539 Type type_b = type_a>
540 Id Binary(Operation operation) {
541 const Id type_def = GetTypeDefinition(result_type);
542 const Id op_a = VisitOperand<type_a>(operation, 0);
543 const Id op_b = VisitOperand<type_b>(operation, 1);
544
545 const Id value = BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a, op_b)));
546 if (IsPrecise(operation)) {
547 Decorate(value, spv::Decoration::NoContraction);
548 }
549 return value;
550 }
551
552 template <Id (Module::*func)(Id, Id, Id, Id), Type result_type, Type type_a = result_type,
553 Type type_b = type_a, Type type_c = type_b>
554 Id Ternary(Operation operation) {
555 const Id type_def = GetTypeDefinition(result_type);
556 const Id op_a = VisitOperand<type_a>(operation, 0);
557 const Id op_b = VisitOperand<type_b>(operation, 1);
558 const Id op_c = VisitOperand<type_c>(operation, 2);
559
560 const Id value = BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a, op_b, op_c)));
561 if (IsPrecise(operation)) {
562 Decorate(value, spv::Decoration::NoContraction);
563 }
564 return value;
565 }
566
567 template <Id (Module::*func)(Id, Id, Id, Id, Id), Type result_type, Type type_a = result_type,
568 Type type_b = type_a, Type type_c = type_b, Type type_d = type_c>
569 Id Quaternary(Operation operation) {
570 const Id type_def = GetTypeDefinition(result_type);
571 const Id op_a = VisitOperand<type_a>(operation, 0);
572 const Id op_b = VisitOperand<type_b>(operation, 1);
573 const Id op_c = VisitOperand<type_c>(operation, 2);
574 const Id op_d = VisitOperand<type_d>(operation, 3);
575
576 const Id value =
577 BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a, op_b, op_c, op_d)));
578 if (IsPrecise(operation)) {
579 Decorate(value, spv::Decoration::NoContraction);
580 }
581 return value;
582 }
583
584 Id Assign(Operation operation) {
585 UNIMPLEMENTED();
586 return {};
587 }
588
589 Id HNegate(Operation operation) {
590 UNIMPLEMENTED();
591 return {};
592 }
593
594 Id HMergeF32(Operation operation) {
595 UNIMPLEMENTED();
596 return {};
597 }
598
599 Id HMergeH0(Operation operation) {
600 UNIMPLEMENTED();
601 return {};
602 }
603
604 Id HMergeH1(Operation operation) {
605 UNIMPLEMENTED();
606 return {};
607 }
608
609 Id HPack2(Operation operation) {
610 UNIMPLEMENTED();
611 return {};
612 }
613
614 Id LogicalAssign(Operation operation) {
615 UNIMPLEMENTED();
616 return {};
617 }
618
619 Id LogicalPick2(Operation operation) {
620 UNIMPLEMENTED();
621 return {};
622 }
623
624 Id LogicalAll2(Operation operation) {
625 UNIMPLEMENTED();
626 return {};
627 }
628
629 Id LogicalAny2(Operation operation) {
630 UNIMPLEMENTED();
631 return {};
632 }
633
634 Id Texture(Operation operation) {
635 UNIMPLEMENTED();
636 return {};
637 }
638
639 Id TextureLod(Operation operation) {
640 UNIMPLEMENTED();
641 return {};
642 }
643
644 Id TextureGather(Operation operation) {
645 UNIMPLEMENTED();
646 return {};
647 }
648
649 Id TextureQueryDimensions(Operation operation) {
650 UNIMPLEMENTED();
651 return {};
652 }
653
654 Id TextureQueryLod(Operation operation) {
655 UNIMPLEMENTED();
656 return {};
657 }
658
659 Id TexelFetch(Operation operation) {
660 UNIMPLEMENTED();
661 return {};
662 }
663
664 Id Branch(Operation operation) {
665 UNIMPLEMENTED();
666 return {};
667 }
668
669 Id PushFlowStack(Operation operation) {
670 UNIMPLEMENTED();
671 return {};
672 }
673
674 Id PopFlowStack(Operation operation) {
675 UNIMPLEMENTED();
676 return {};
677 }
678
679 Id Exit(Operation operation) {
680 UNIMPLEMENTED();
681 return {};
682 }
683
684 Id Discard(Operation operation) {
685 UNIMPLEMENTED();
686 return {};
687 }
688
689 Id EmitVertex(Operation operation) {
690 UNIMPLEMENTED();
691 return {};
692 }
693
694 Id EndPrimitive(Operation operation) {
695 UNIMPLEMENTED();
696 return {};
697 }
698
699 Id YNegate(Operation operation) {
700 UNIMPLEMENTED();
701 return {};
702 }
703
503 Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type, 704 Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type,
504 const std::string& name) { 705 const std::string& name) {
505 const Id id = OpVariable(type, storage); 706 const Id id = OpVariable(type, storage);
@@ -518,6 +719,215 @@ private:
518 return false; 719 return false;
519 } 720 }
520 721
722 template <Type type>
723 Id VisitOperand(Operation operation, std::size_t operand_index) {
724 const Id value = Visit(operation[operand_index]);
725
726 switch (type) {
727 case Type::Bool:
728 case Type::Bool2:
729 case Type::Float:
730 return value;
731 case Type::Int:
732 return Emit(OpBitcast(t_int, value));
733 case Type::Uint:
734 return Emit(OpBitcast(t_uint, value));
735 case Type::HalfFloat:
736 UNIMPLEMENTED();
737 }
738 UNREACHABLE();
739 return value;
740 }
741
742 template <Type type>
743 Id BitcastFrom(Id value) {
744 switch (type) {
745 case Type::Bool:
746 case Type::Bool2:
747 case Type::Float:
748 return value;
749 case Type::Int:
750 case Type::Uint:
751 return Emit(OpBitcast(t_float, value));
752 case Type::HalfFloat:
753 UNIMPLEMENTED();
754 }
755 UNREACHABLE();
756 return value;
757 }
758
759 template <Type type>
760 Id BitcastTo(Id value) {
761 switch (type) {
762 case Type::Bool:
763 case Type::Bool2:
764 UNREACHABLE();
765 case Type::Float:
766 return Emit(OpBitcast(t_float, value));
767 case Type::Int:
768 return Emit(OpBitcast(t_int, value));
769 case Type::Uint:
770 return Emit(OpBitcast(t_uint, value));
771 case Type::HalfFloat:
772 UNIMPLEMENTED();
773 }
774 UNREACHABLE();
775 return value;
776 }
777
778 Id GetTypeDefinition(Type type) {
779 switch (type) {
780 case Type::Bool:
781 return t_bool;
782 case Type::Bool2:
783 return t_bool2;
784 case Type::Float:
785 return t_float;
786 case Type::Int:
787 return t_int;
788 case Type::Uint:
789 return t_uint;
790 case Type::HalfFloat:
791 UNIMPLEMENTED();
792 }
793 UNREACHABLE();
794 return {};
795 }
796
797 static constexpr OperationDecompilersArray operation_decompilers = {
798 &SPIRVDecompiler::Assign,
799
800 &SPIRVDecompiler::Ternary<&Module::OpSelect, Type::Float, Type::Bool, Type::Float,
801 Type::Float>,
802
803 &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::Float>,
804 &SPIRVDecompiler::Binary<&Module::OpFMul, Type::Float>,
805 &SPIRVDecompiler::Binary<&Module::OpFDiv, Type::Float>,
806 &SPIRVDecompiler::Ternary<&Module::OpFma, Type::Float>,
807 &SPIRVDecompiler::Unary<&Module::OpFNegate, Type::Float>,
808 &SPIRVDecompiler::Unary<&Module::OpFAbs, Type::Float>,
809 &SPIRVDecompiler::Ternary<&Module::OpFClamp, Type::Float>,
810 &SPIRVDecompiler::Binary<&Module::OpFMin, Type::Float>,
811 &SPIRVDecompiler::Binary<&Module::OpFMax, Type::Float>,
812 &SPIRVDecompiler::Unary<&Module::OpCos, Type::Float>,
813 &SPIRVDecompiler::Unary<&Module::OpSin, Type::Float>,
814 &SPIRVDecompiler::Unary<&Module::OpExp2, Type::Float>,
815 &SPIRVDecompiler::Unary<&Module::OpLog2, Type::Float>,
816 &SPIRVDecompiler::Unary<&Module::OpInverseSqrt, Type::Float>,
817 &SPIRVDecompiler::Unary<&Module::OpSqrt, Type::Float>,
818 &SPIRVDecompiler::Unary<&Module::OpRoundEven, Type::Float>,
819 &SPIRVDecompiler::Unary<&Module::OpFloor, Type::Float>,
820 &SPIRVDecompiler::Unary<&Module::OpCeil, Type::Float>,
821 &SPIRVDecompiler::Unary<&Module::OpTrunc, Type::Float>,
822 &SPIRVDecompiler::Unary<&Module::OpConvertSToF, Type::Float, Type::Int>,
823 &SPIRVDecompiler::Unary<&Module::OpConvertUToF, Type::Float, Type::Uint>,
824
825 &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Int>,
826 &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Int>,
827 &SPIRVDecompiler::Binary<&Module::OpSDiv, Type::Int>,
828 &SPIRVDecompiler::Unary<&Module::OpSNegate, Type::Int>,
829 &SPIRVDecompiler::Unary<&Module::OpSAbs, Type::Int>,
830 &SPIRVDecompiler::Binary<&Module::OpSMin, Type::Int>,
831 &SPIRVDecompiler::Binary<&Module::OpSMax, Type::Int>,
832
833 &SPIRVDecompiler::Unary<&Module::OpConvertFToS, Type::Int, Type::Float>,
834 &SPIRVDecompiler::Unary<&Module::OpBitcast, Type::Int, Type::Uint>,
835 &SPIRVDecompiler::Binary<&Module::OpShiftLeftLogical, Type::Int, Type::Int, Type::Uint>,
836 &SPIRVDecompiler::Binary<&Module::OpShiftRightLogical, Type::Int, Type::Int, Type::Uint>,
837 &SPIRVDecompiler::Binary<&Module::OpShiftRightArithmetic, Type::Int, Type::Int, Type::Uint>,
838 &SPIRVDecompiler::Binary<&Module::OpBitwiseAnd, Type::Int>,
839 &SPIRVDecompiler::Binary<&Module::OpBitwiseOr, Type::Int>,
840 &SPIRVDecompiler::Binary<&Module::OpBitwiseXor, Type::Int>,
841 &SPIRVDecompiler::Unary<&Module::OpNot, Type::Int>,
842 &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>,
843 &SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>,
844 &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>,
845
846 &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>,
847 &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>,
848 &SPIRVDecompiler::Binary<&Module::OpUDiv, Type::Uint>,
849 &SPIRVDecompiler::Binary<&Module::OpUMin, Type::Uint>,
850 &SPIRVDecompiler::Binary<&Module::OpUMax, Type::Uint>,
851 &SPIRVDecompiler::Unary<&Module::OpConvertFToU, Type::Uint, Type::Float>,
852 &SPIRVDecompiler::Unary<&Module::OpBitcast, Type::Uint, Type::Int>,
853 &SPIRVDecompiler::Binary<&Module::OpShiftLeftLogical, Type::Uint>,
854 &SPIRVDecompiler::Binary<&Module::OpShiftRightLogical, Type::Uint>,
855 &SPIRVDecompiler::Binary<&Module::OpShiftRightArithmetic, Type::Uint>,
856 &SPIRVDecompiler::Binary<&Module::OpBitwiseAnd, Type::Uint>,
857 &SPIRVDecompiler::Binary<&Module::OpBitwiseOr, Type::Uint>,
858 &SPIRVDecompiler::Binary<&Module::OpBitwiseXor, Type::Uint>,
859 &SPIRVDecompiler::Unary<&Module::OpNot, Type::Uint>,
860 &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>,
861 &SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>,
862 &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>,
863
864 &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>,
865 &SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>,
866 &SPIRVDecompiler::Ternary<&Module::OpFma, Type::HalfFloat>,
867 &SPIRVDecompiler::Unary<&Module::OpFAbs, Type::HalfFloat>,
868 &SPIRVDecompiler::HNegate,
869 &SPIRVDecompiler::HMergeF32,
870 &SPIRVDecompiler::HMergeH0,
871 &SPIRVDecompiler::HMergeH1,
872 &SPIRVDecompiler::HPack2,
873
874 &SPIRVDecompiler::LogicalAssign,
875 &SPIRVDecompiler::Binary<&Module::OpLogicalAnd, Type::Bool>,
876 &SPIRVDecompiler::Binary<&Module::OpLogicalOr, Type::Bool>,
877 &SPIRVDecompiler::Binary<&Module::OpLogicalNotEqual, Type::Bool>,
878 &SPIRVDecompiler::Unary<&Module::OpLogicalNot, Type::Bool>,
879 &SPIRVDecompiler::LogicalPick2,
880 &SPIRVDecompiler::LogicalAll2,
881 &SPIRVDecompiler::LogicalAny2,
882
883 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool, Type::Float>,
884 &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool, Type::Float>,
885 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool, Type::Float>,
886 &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThan, Type::Bool, Type::Float>,
887 &SPIRVDecompiler::Binary<&Module::OpFOrdNotEqual, Type::Bool, Type::Float>,
888 &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThanEqual, Type::Bool, Type::Float>,
889 &SPIRVDecompiler::Unary<&Module::OpIsNan, Type::Bool>,
890
891 &SPIRVDecompiler::Binary<&Module::OpSLessThan, Type::Bool, Type::Int>,
892 &SPIRVDecompiler::Binary<&Module::OpIEqual, Type::Bool, Type::Int>,
893 &SPIRVDecompiler::Binary<&Module::OpSLessThanEqual, Type::Bool, Type::Int>,
894 &SPIRVDecompiler::Binary<&Module::OpSGreaterThan, Type::Bool, Type::Int>,
895 &SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Int>,
896 &SPIRVDecompiler::Binary<&Module::OpSGreaterThanEqual, Type::Bool, Type::Int>,
897
898 &SPIRVDecompiler::Binary<&Module::OpULessThan, Type::Bool, Type::Uint>,
899 &SPIRVDecompiler::Binary<&Module::OpIEqual, Type::Bool, Type::Uint>,
900 &SPIRVDecompiler::Binary<&Module::OpULessThanEqual, Type::Bool, Type::Uint>,
901 &SPIRVDecompiler::Binary<&Module::OpUGreaterThan, Type::Bool, Type::Uint>,
902 &SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Uint>,
903 &SPIRVDecompiler::Binary<&Module::OpUGreaterThanEqual, Type::Bool, Type::Uint>,
904
905 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool, Type::HalfFloat>,
906 &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool, Type::HalfFloat>,
907 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool, Type::HalfFloat>,
908 &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThan, Type::Bool, Type::HalfFloat>,
909 &SPIRVDecompiler::Binary<&Module::OpFOrdNotEqual, Type::Bool, Type::HalfFloat>,
910 &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThanEqual, Type::Bool, Type::HalfFloat>,
911
912 &SPIRVDecompiler::Texture,
913 &SPIRVDecompiler::TextureLod,
914 &SPIRVDecompiler::TextureGather,
915 &SPIRVDecompiler::TextureQueryDimensions,
916 &SPIRVDecompiler::TextureQueryLod,
917 &SPIRVDecompiler::TexelFetch,
918
919 &SPIRVDecompiler::Branch,
920 &SPIRVDecompiler::PushFlowStack,
921 &SPIRVDecompiler::PopFlowStack,
922 &SPIRVDecompiler::Exit,
923 &SPIRVDecompiler::Discard,
924
925 &SPIRVDecompiler::EmitVertex,
926 &SPIRVDecompiler::EndPrimitive,
927
928 &SPIRVDecompiler::YNegate,
929 };
930
521 const ShaderIR& ir; 931 const ShaderIR& ir;
522 const ShaderStage stage; 932 const ShaderStage stage;
523 const Tegra::Shader::Header header; 933 const Tegra::Shader::Header header;