summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-15 22:46:11 -0300
committerGravatar ameerj2021-07-22 21:51:27 -0400
commit183855e396cc6918d36fbf3e38ea426e934b4e3e (patch)
treea665794753520c09a1d34d8a086352894ec1cb72 /src/shader_recompiler/frontend/ir
parentshader: Mark atomic instructions as writes (diff)
downloadyuzu-183855e396cc6918d36fbf3e38ea426e934b4e3e.tar.gz
yuzu-183855e396cc6918d36fbf3e38ea426e934b4e3e.tar.xz
yuzu-183855e396cc6918d36fbf3e38ea426e934b4e3e.zip
shader: Implement tessellation shaders, polygon mode and invocation id
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp12
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h4
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp1
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.cpp1
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc3
-rw-r--r--src/shader_recompiler/frontend/ir/patch.cpp28
-rw-r--r--src/shader_recompiler/frontend/ir/patch.h149
-rw-r--r--src/shader_recompiler/frontend/ir/type.h41
-rw-r--r--src/shader_recompiler/frontend/ir/value.cpp9
-rw-r--r--src/shader_recompiler/frontend/ir/value.h4
10 files changed, 232 insertions, 20 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index d66eb17a6..b821d9f47 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -331,6 +331,14 @@ void IREmitter::SetAttributeIndexed(const U32& phys_address, const F32& value, c
331 Inst(Opcode::SetAttributeIndexed, phys_address, value, vertex); 331 Inst(Opcode::SetAttributeIndexed, phys_address, value, vertex);
332} 332}
333 333
334F32 IREmitter::GetPatch(Patch patch) {
335 return Inst<F32>(Opcode::GetPatch, patch);
336}
337
338void IREmitter::SetPatch(Patch patch, const F32& value) {
339 Inst(Opcode::SetPatch, patch, value);
340}
341
334void IREmitter::SetFragColor(u32 index, u32 component, const F32& value) { 342void IREmitter::SetFragColor(u32 index, u32 component, const F32& value) {
335 Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value); 343 Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value);
336} 344}
@@ -363,6 +371,10 @@ U32 IREmitter::LocalInvocationIdZ() {
363 return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 2)}; 371 return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 2)};
364} 372}
365 373
374U32 IREmitter::InvocationId() {
375 return Inst<U32>(Opcode::InvocationId);
376}
377
366U1 IREmitter::IsHelperInvocation() { 378U1 IREmitter::IsHelperInvocation() {
367 return Inst<U1>(Opcode::IsHelperInvocation); 379 return Inst<U1>(Opcode::IsHelperInvocation);
368} 380}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index e70359eb1..7f8f1ad42 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -84,6 +84,9 @@ public:
84 [[nodiscard]] F32 GetAttributeIndexed(const U32& phys_address, const U32& vertex); 84 [[nodiscard]] F32 GetAttributeIndexed(const U32& phys_address, const U32& vertex);
85 void SetAttributeIndexed(const U32& phys_address, const F32& value, const U32& vertex); 85 void SetAttributeIndexed(const U32& phys_address, const F32& value, const U32& vertex);
86 86
87 [[nodiscard]] F32 GetPatch(Patch patch);
88 void SetPatch(Patch patch, const F32& value);
89
87 void SetFragColor(u32 index, u32 component, const F32& value); 90 void SetFragColor(u32 index, u32 component, const F32& value);
88 void SetFragDepth(const F32& value); 91 void SetFragDepth(const F32& value);
89 92
@@ -95,6 +98,7 @@ public:
95 [[nodiscard]] U32 LocalInvocationIdY(); 98 [[nodiscard]] U32 LocalInvocationIdY();
96 [[nodiscard]] U32 LocalInvocationIdZ(); 99 [[nodiscard]] U32 LocalInvocationIdZ();
97 100
101 [[nodiscard]] U32 InvocationId();
98 [[nodiscard]] U1 IsHelperInvocation(); 102 [[nodiscard]] U1 IsHelperInvocation();
99 103
100 [[nodiscard]] U32 LaneId(); 104 [[nodiscard]] U32 LaneId();
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp
index 204c55fa8..b2d7573d9 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.cpp
+++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp
@@ -73,6 +73,7 @@ bool Inst::MayHaveSideEffects() const noexcept {
73 case Opcode::EndPrimitive: 73 case Opcode::EndPrimitive:
74 case Opcode::SetAttribute: 74 case Opcode::SetAttribute:
75 case Opcode::SetAttributeIndexed: 75 case Opcode::SetAttributeIndexed:
76 case Opcode::SetPatch:
76 case Opcode::SetFragColor: 77 case Opcode::SetFragColor:
77 case Opcode::SetFragDepth: 78 case Opcode::SetFragDepth:
78 case Opcode::WriteGlobalU8: 79 case Opcode::WriteGlobalU8:
diff --git a/src/shader_recompiler/frontend/ir/opcodes.cpp b/src/shader_recompiler/frontend/ir/opcodes.cpp
index 7d3e0b2ab..7f04b647b 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.cpp
+++ b/src/shader_recompiler/frontend/ir/opcodes.cpp
@@ -24,6 +24,7 @@ constexpr Type Label{Type::Label};
24constexpr Type Reg{Type::Reg}; 24constexpr Type Reg{Type::Reg};
25constexpr Type Pred{Type::Pred}; 25constexpr Type Pred{Type::Pred};
26constexpr Type Attribute{Type::Attribute}; 26constexpr Type Attribute{Type::Attribute};
27constexpr Type Patch{Type::Patch};
27constexpr Type U1{Type::U1}; 28constexpr Type U1{Type::U1};
28constexpr Type U8{Type::U8}; 29constexpr Type U8{Type::U8};
29constexpr Type U16{Type::U16}; 30constexpr Type U16{Type::U16};
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 7a21fe746..a86542cd8 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -48,6 +48,8 @@ OPCODE(GetAttribute, F32, Attr
48OPCODE(SetAttribute, Void, Attribute, F32, U32, ) 48OPCODE(SetAttribute, Void, Attribute, F32, U32, )
49OPCODE(GetAttributeIndexed, F32, U32, U32, ) 49OPCODE(GetAttributeIndexed, F32, U32, U32, )
50OPCODE(SetAttributeIndexed, Void, U32, F32, U32, ) 50OPCODE(SetAttributeIndexed, Void, U32, F32, U32, )
51OPCODE(GetPatch, F32, Patch, )
52OPCODE(SetPatch, Void, Patch, F32, )
51OPCODE(SetFragColor, Void, U32, U32, F32, ) 53OPCODE(SetFragColor, Void, U32, U32, F32, )
52OPCODE(SetFragDepth, Void, F32, ) 54OPCODE(SetFragDepth, Void, F32, )
53OPCODE(GetZFlag, U1, Void, ) 55OPCODE(GetZFlag, U1, Void, )
@@ -60,6 +62,7 @@ OPCODE(SetCFlag, Void, U1,
60OPCODE(SetOFlag, Void, U1, ) 62OPCODE(SetOFlag, Void, U1, )
61OPCODE(WorkgroupId, U32x3, ) 63OPCODE(WorkgroupId, U32x3, )
62OPCODE(LocalInvocationId, U32x3, ) 64OPCODE(LocalInvocationId, U32x3, )
65OPCODE(InvocationId, U32, )
63OPCODE(IsHelperInvocation, U1, ) 66OPCODE(IsHelperInvocation, U1, )
64 67
65// Undefined 68// Undefined
diff --git a/src/shader_recompiler/frontend/ir/patch.cpp b/src/shader_recompiler/frontend/ir/patch.cpp
new file mode 100644
index 000000000..1f770bc48
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/patch.cpp
@@ -0,0 +1,28 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "shader_recompiler/frontend/ir/patch.h"
6#include "shader_recompiler/exception.h"
7
8namespace Shader::IR {
9
10bool IsGeneric(Patch patch) noexcept {
11 return patch >= Patch::Component0 && patch <= Patch::Component119;
12}
13
14u32 GenericPatchIndex(Patch patch) {
15 if (!IsGeneric(patch)) {
16 throw InvalidArgument("Patch {} is not generic", patch);
17 }
18 return (static_cast<u32>(patch) - static_cast<u32>(Patch::Component0)) / 4;
19}
20
21u32 GenericPatchElement(Patch patch) {
22 if (!IsGeneric(patch)) {
23 throw InvalidArgument("Patch {} is not generic", patch);
24 }
25 return (static_cast<u32>(patch) - static_cast<u32>(Patch::Component0)) % 4;
26}
27
28} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/patch.h b/src/shader_recompiler/frontend/ir/patch.h
new file mode 100644
index 000000000..6d66ff0d6
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/patch.h
@@ -0,0 +1,149 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9namespace Shader::IR {
10
11enum class Patch : u64 {
12 TessellationLodLeft,
13 TessellationLodTop,
14 TessellationLodRight,
15 TessellationLodBottom,
16 TessellationLodInteriorU,
17 TessellationLodInteriorV,
18 ComponentPadding0,
19 ComponentPadding1,
20 Component0,
21 Component1,
22 Component2,
23 Component3,
24 Component4,
25 Component5,
26 Component6,
27 Component7,
28 Component8,
29 Component9,
30 Component10,
31 Component11,
32 Component12,
33 Component13,
34 Component14,
35 Component15,
36 Component16,
37 Component17,
38 Component18,
39 Component19,
40 Component20,
41 Component21,
42 Component22,
43 Component23,
44 Component24,
45 Component25,
46 Component26,
47 Component27,
48 Component28,
49 Component29,
50 Component30,
51 Component31,
52 Component32,
53 Component33,
54 Component34,
55 Component35,
56 Component36,
57 Component37,
58 Component38,
59 Component39,
60 Component40,
61 Component41,
62 Component42,
63 Component43,
64 Component44,
65 Component45,
66 Component46,
67 Component47,
68 Component48,
69 Component49,
70 Component50,
71 Component51,
72 Component52,
73 Component53,
74 Component54,
75 Component55,
76 Component56,
77 Component57,
78 Component58,
79 Component59,
80 Component60,
81 Component61,
82 Component62,
83 Component63,
84 Component64,
85 Component65,
86 Component66,
87 Component67,
88 Component68,
89 Component69,
90 Component70,
91 Component71,
92 Component72,
93 Component73,
94 Component74,
95 Component75,
96 Component76,
97 Component77,
98 Component78,
99 Component79,
100 Component80,
101 Component81,
102 Component82,
103 Component83,
104 Component84,
105 Component85,
106 Component86,
107 Component87,
108 Component88,
109 Component89,
110 Component90,
111 Component91,
112 Component92,
113 Component93,
114 Component94,
115 Component95,
116 Component96,
117 Component97,
118 Component98,
119 Component99,
120 Component100,
121 Component101,
122 Component102,
123 Component103,
124 Component104,
125 Component105,
126 Component106,
127 Component107,
128 Component108,
129 Component109,
130 Component110,
131 Component111,
132 Component112,
133 Component113,
134 Component114,
135 Component115,
136 Component116,
137 Component117,
138 Component118,
139 Component119,
140};
141static_assert(static_cast<u64>(Patch::Component119) == 127);
142
143[[nodiscard]] bool IsGeneric(Patch patch) noexcept;
144
145[[nodiscard]] u32 GenericPatchIndex(Patch patch);
146
147[[nodiscard]] u32 GenericPatchElement(Patch patch);
148
149} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/type.h b/src/shader_recompiler/frontend/ir/type.h
index 9a32ca1e8..8b3b33852 100644
--- a/src/shader_recompiler/frontend/ir/type.h
+++ b/src/shader_recompiler/frontend/ir/type.h
@@ -20,26 +20,27 @@ enum class Type {
20 Reg = 1 << 2, 20 Reg = 1 << 2,
21 Pred = 1 << 3, 21 Pred = 1 << 3,
22 Attribute = 1 << 4, 22 Attribute = 1 << 4,
23 U1 = 1 << 5, 23 Patch = 1 << 5,
24 U8 = 1 << 6, 24 U1 = 1 << 6,
25 U16 = 1 << 7, 25 U8 = 1 << 7,
26 U32 = 1 << 8, 26 U16 = 1 << 8,
27 U64 = 1 << 9, 27 U32 = 1 << 9,
28 F16 = 1 << 10, 28 U64 = 1 << 10,
29 F32 = 1 << 11, 29 F16 = 1 << 11,
30 F64 = 1 << 12, 30 F32 = 1 << 12,
31 U32x2 = 1 << 13, 31 F64 = 1 << 13,
32 U32x3 = 1 << 14, 32 U32x2 = 1 << 14,
33 U32x4 = 1 << 15, 33 U32x3 = 1 << 15,
34 F16x2 = 1 << 16, 34 U32x4 = 1 << 16,
35 F16x3 = 1 << 17, 35 F16x2 = 1 << 17,
36 F16x4 = 1 << 18, 36 F16x3 = 1 << 18,
37 F32x2 = 1 << 19, 37 F16x4 = 1 << 19,
38 F32x3 = 1 << 20, 38 F32x2 = 1 << 20,
39 F32x4 = 1 << 21, 39 F32x3 = 1 << 21,
40 F64x2 = 1 << 22, 40 F32x4 = 1 << 22,
41 F64x3 = 1 << 23, 41 F64x2 = 1 << 23,
42 F64x4 = 1 << 24, 42 F64x3 = 1 << 24,
43 F64x4 = 1 << 25,
43}; 44};
44DECLARE_ENUM_FLAG_OPERATORS(Type) 45DECLARE_ENUM_FLAG_OPERATORS(Type)
45 46
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp
index 1e7ffb86d..bf5f8c0c2 100644
--- a/src/shader_recompiler/frontend/ir/value.cpp
+++ b/src/shader_recompiler/frontend/ir/value.cpp
@@ -18,6 +18,8 @@ Value::Value(IR::Pred value) noexcept : type{Type::Pred}, pred{value} {}
18 18
19Value::Value(IR::Attribute value) noexcept : type{Type::Attribute}, attribute{value} {} 19Value::Value(IR::Attribute value) noexcept : type{Type::Attribute}, attribute{value} {}
20 20
21Value::Value(IR::Patch value) noexcept : type{Type::Patch}, patch{value} {}
22
21Value::Value(bool value) noexcept : type{Type::U1}, imm_u1{value} {} 23Value::Value(bool value) noexcept : type{Type::U1}, imm_u1{value} {}
22 24
23Value::Value(u8 value) noexcept : type{Type::U8}, imm_u8{value} {} 25Value::Value(u8 value) noexcept : type{Type::U8}, imm_u8{value} {}
@@ -109,6 +111,11 @@ IR::Attribute Value::Attribute() const {
109 return attribute; 111 return attribute;
110} 112}
111 113
114IR::Patch Value::Patch() const {
115 ValidateAccess(Type::Patch);
116 return patch;
117}
118
112bool Value::U1() const { 119bool Value::U1() const {
113 if (IsIdentity()) { 120 if (IsIdentity()) {
114 return inst->Arg(0).U1(); 121 return inst->Arg(0).U1();
@@ -182,6 +189,8 @@ bool Value::operator==(const Value& other) const {
182 return pred == other.pred; 189 return pred == other.pred;
183 case Type::Attribute: 190 case Type::Attribute:
184 return attribute == other.attribute; 191 return attribute == other.attribute;
192 case Type::Patch:
193 return patch == other.patch;
185 case Type::U1: 194 case Type::U1:
186 return imm_u1 == other.imm_u1; 195 return imm_u1 == other.imm_u1;
187 case Type::U8: 196 case Type::U8:
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h
index a0962863d..303745563 100644
--- a/src/shader_recompiler/frontend/ir/value.h
+++ b/src/shader_recompiler/frontend/ir/value.h
@@ -9,6 +9,7 @@
9#include "shader_recompiler/frontend/ir/attribute.h" 9#include "shader_recompiler/frontend/ir/attribute.h"
10#include "shader_recompiler/frontend/ir/pred.h" 10#include "shader_recompiler/frontend/ir/pred.h"
11#include "shader_recompiler/frontend/ir/reg.h" 11#include "shader_recompiler/frontend/ir/reg.h"
12#include "shader_recompiler/frontend/ir/patch.h"
12#include "shader_recompiler/frontend/ir/type.h" 13#include "shader_recompiler/frontend/ir/type.h"
13 14
14namespace Shader::IR { 15namespace Shader::IR {
@@ -24,6 +25,7 @@ public:
24 explicit Value(IR::Reg value) noexcept; 25 explicit Value(IR::Reg value) noexcept;
25 explicit Value(IR::Pred value) noexcept; 26 explicit Value(IR::Pred value) noexcept;
26 explicit Value(IR::Attribute value) noexcept; 27 explicit Value(IR::Attribute value) noexcept;
28 explicit Value(IR::Patch value) noexcept;
27 explicit Value(bool value) noexcept; 29 explicit Value(bool value) noexcept;
28 explicit Value(u8 value) noexcept; 30 explicit Value(u8 value) noexcept;
29 explicit Value(u16 value) noexcept; 31 explicit Value(u16 value) noexcept;
@@ -46,6 +48,7 @@ public:
46 [[nodiscard]] IR::Reg Reg() const; 48 [[nodiscard]] IR::Reg Reg() const;
47 [[nodiscard]] IR::Pred Pred() const; 49 [[nodiscard]] IR::Pred Pred() const;
48 [[nodiscard]] IR::Attribute Attribute() const; 50 [[nodiscard]] IR::Attribute Attribute() const;
51 [[nodiscard]] IR::Patch Patch() const;
49 [[nodiscard]] bool U1() const; 52 [[nodiscard]] bool U1() const;
50 [[nodiscard]] u8 U8() const; 53 [[nodiscard]] u8 U8() const;
51 [[nodiscard]] u16 U16() const; 54 [[nodiscard]] u16 U16() const;
@@ -67,6 +70,7 @@ private:
67 IR::Reg reg; 70 IR::Reg reg;
68 IR::Pred pred; 71 IR::Pred pred;
69 IR::Attribute attribute; 72 IR::Attribute attribute;
73 IR::Patch patch;
70 bool imm_u1; 74 bool imm_u1;
71 u8 imm_u8; 75 u8 imm_u8;
72 u16 imm_u16; 76 u16 imm_u16;