summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp29
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h6
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h103
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp28
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp48
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp89
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp48
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp16
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp72
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp22
12 files changed, 255 insertions, 210 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index 770067d98..ea1c8a3be 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -30,8 +30,11 @@ EmitContext::EmitContext(IR::Program& program) : Sirit::Module(0x00010000) {
30 DefineCommonTypes(program.info); 30 DefineCommonTypes(program.info);
31 DefineCommonConstants(); 31 DefineCommonConstants();
32 DefineSpecialVariables(program.info); 32 DefineSpecialVariables(program.info);
33 DefineConstantBuffers(program.info); 33
34 DefineStorageBuffers(program.info); 34 u32 binding{};
35 DefineConstantBuffers(program.info, binding);
36 DefineStorageBuffers(program.info, binding);
37
35 DefineLabels(program); 38 DefineLabels(program);
36} 39}
37 40
@@ -58,6 +61,12 @@ void EmitContext::DefineCommonTypes(const Info& info) {
58 61
59 U1 = Name(TypeBool(), "u1"); 62 U1 = Name(TypeBool(), "u1");
60 63
64 // TODO: Conditionally define these
65 AddCapability(spv::Capability::Int16);
66 AddCapability(spv::Capability::Int64);
67 U16 = Name(TypeInt(16, false), "u16");
68 U64 = Name(TypeInt(64, false), "u64");
69
61 F32.Define(*this, TypeFloat(32), "f32"); 70 F32.Define(*this, TypeFloat(32), "f32");
62 U32.Define(*this, TypeInt(32, false), "u32"); 71 U32.Define(*this, TypeInt(32, false), "u32");
63 72
@@ -95,12 +104,12 @@ void EmitContext::DefineSpecialVariables(const Info& info) {
95 } 104 }
96} 105}
97 106
98void EmitContext::DefineConstantBuffers(const Info& info) { 107void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) {
99 if (info.constant_buffer_descriptors.empty()) { 108 if (info.constant_buffer_descriptors.empty()) {
100 return; 109 return;
101 } 110 }
102 const Id array_type{TypeArray(U32[1], Constant(U32[1], 4096))}; 111 const Id array_type{TypeArray(U32[1], Constant(U32[1], 4096))};
103 Decorate(array_type, spv::Decoration::ArrayStride, 16U); 112 Decorate(array_type, spv::Decoration::ArrayStride, 4U);
104 113
105 const Id struct_type{TypeStruct(array_type)}; 114 const Id struct_type{TypeStruct(array_type)};
106 Name(struct_type, "cbuf_block"); 115 Name(struct_type, "cbuf_block");
@@ -111,18 +120,19 @@ void EmitContext::DefineConstantBuffers(const Info& info) {
111 const Id uniform_type{TypePointer(spv::StorageClass::Uniform, struct_type)}; 120 const Id uniform_type{TypePointer(spv::StorageClass::Uniform, struct_type)};
112 uniform_u32 = TypePointer(spv::StorageClass::Uniform, U32[1]); 121 uniform_u32 = TypePointer(spv::StorageClass::Uniform, U32[1]);
113 122
114 u32 binding{}; 123 u32 index{};
115 for (const Info::ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { 124 for (const Info::ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) {
116 const Id id{AddGlobalVariable(uniform_type, spv::StorageClass::Uniform)}; 125 const Id id{AddGlobalVariable(uniform_type, spv::StorageClass::Uniform)};
117 Decorate(id, spv::Decoration::Binding, binding); 126 Decorate(id, spv::Decoration::Binding, binding);
118 Decorate(id, spv::Decoration::DescriptorSet, 0U); 127 Decorate(id, spv::Decoration::DescriptorSet, 0U);
119 Name(id, fmt::format("c{}", desc.index)); 128 Name(id, fmt::format("c{}", desc.index));
120 std::fill_n(cbufs.data() + desc.index, desc.count, id); 129 std::fill_n(cbufs.data() + desc.index, desc.count, id);
130 index += desc.count;
121 binding += desc.count; 131 binding += desc.count;
122 } 132 }
123} 133}
124 134
125void EmitContext::DefineStorageBuffers(const Info& info) { 135void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) {
126 if (info.storage_buffers_descriptors.empty()) { 136 if (info.storage_buffers_descriptors.empty()) {
127 return; 137 return;
128 } 138 }
@@ -140,13 +150,14 @@ void EmitContext::DefineStorageBuffers(const Info& info) {
140 const Id storage_type{TypePointer(spv::StorageClass::StorageBuffer, struct_type)}; 150 const Id storage_type{TypePointer(spv::StorageClass::StorageBuffer, struct_type)};
141 storage_u32 = TypePointer(spv::StorageClass::StorageBuffer, U32[1]); 151 storage_u32 = TypePointer(spv::StorageClass::StorageBuffer, U32[1]);
142 152
143 u32 binding{}; 153 u32 index{};
144 for (const Info::StorageBufferDescriptor& desc : info.storage_buffers_descriptors) { 154 for (const Info::StorageBufferDescriptor& desc : info.storage_buffers_descriptors) {
145 const Id id{AddGlobalVariable(storage_type, spv::StorageClass::StorageBuffer)}; 155 const Id id{AddGlobalVariable(storage_type, spv::StorageClass::StorageBuffer)};
146 Decorate(id, spv::Decoration::Binding, binding); 156 Decorate(id, spv::Decoration::Binding, binding);
147 Decorate(id, spv::Decoration::DescriptorSet, 0U); 157 Decorate(id, spv::Decoration::DescriptorSet, 0U);
148 Name(id, fmt::format("ssbo{}", binding)); 158 Name(id, fmt::format("ssbo{}", index));
149 std::fill_n(ssbos.data() + binding, desc.count, id); 159 std::fill_n(ssbos.data() + index, desc.count, id);
160 index += desc.count;
150 binding += desc.count; 161 binding += desc.count;
151 } 162 }
152} 163}
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index c4b84759d..8de203da2 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -37,6 +37,8 @@ public:
37 37
38 Id void_id{}; 38 Id void_id{};
39 Id U1{}; 39 Id U1{};
40 Id U16{};
41 Id U64{};
40 VectorTypes F32; 42 VectorTypes F32;
41 VectorTypes U32; 43 VectorTypes U32;
42 VectorTypes F16; 44 VectorTypes F16;
@@ -59,8 +61,8 @@ private:
59 void DefineCommonTypes(const Info& info); 61 void DefineCommonTypes(const Info& info);
60 void DefineCommonConstants(); 62 void DefineCommonConstants();
61 void DefineSpecialVariables(const Info& info); 63 void DefineSpecialVariables(const Info& info);
62 void DefineConstantBuffers(const Info& info); 64 void DefineConstantBuffers(const Info& info, u32& binding);
63 void DefineStorageBuffers(const Info& info); 65 void DefineStorageBuffers(const Info& info, u32& binding);
64 void DefineLabels(IR::Program& program); 66 void DefineLabels(IR::Program& program);
65}; 67};
66 68
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index d59718435..4ce07c281 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -14,6 +14,8 @@
14#include "shader_recompiler/frontend/ir/microinstruction.h" 14#include "shader_recompiler/frontend/ir/microinstruction.h"
15#include "shader_recompiler/frontend/ir/program.h" 15#include "shader_recompiler/frontend/ir/program.h"
16 16
17#pragma optimize("", off)
18
17namespace Shader::Backend::SPIRV { 19namespace Shader::Backend::SPIRV {
18namespace { 20namespace {
19template <class Func> 21template <class Func>
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 5813f51ff..2b59c0b72 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -79,26 +79,27 @@ void EmitWriteStorageU16(EmitContext& ctx);
79void EmitWriteStorageS16(EmitContext& ctx); 79void EmitWriteStorageS16(EmitContext& ctx);
80void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, 80void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
81 Id value); 81 Id value);
82void EmitWriteStorage64(EmitContext& ctx); 82void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
83 Id value);
83void EmitWriteStorage128(EmitContext& ctx); 84void EmitWriteStorage128(EmitContext& ctx);
84void EmitCompositeConstructU32x2(EmitContext& ctx); 85Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2);
85void EmitCompositeConstructU32x3(EmitContext& ctx); 86Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3);
86void EmitCompositeConstructU32x4(EmitContext& ctx); 87Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4);
87void EmitCompositeExtractU32x2(EmitContext& ctx); 88Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index);
88Id EmitCompositeExtractU32x3(EmitContext& ctx, Id vector, u32 index); 89Id EmitCompositeExtractU32x3(EmitContext& ctx, Id composite, u32 index);
89void EmitCompositeExtractU32x4(EmitContext& ctx); 90Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index);
90void EmitCompositeConstructF16x2(EmitContext& ctx); 91void EmitCompositeConstructF16x2(EmitContext& ctx);
91void EmitCompositeConstructF16x3(EmitContext& ctx); 92void EmitCompositeConstructF16x3(EmitContext& ctx);
92void EmitCompositeConstructF16x4(EmitContext& ctx); 93void EmitCompositeConstructF16x4(EmitContext& ctx);
93void EmitCompositeExtractF16x2(EmitContext& ctx); 94Id EmitCompositeExtractF16x2(EmitContext& ctx, Id composite, u32 index);
94void EmitCompositeExtractF16x3(EmitContext& ctx); 95Id EmitCompositeExtractF16x3(EmitContext& ctx, Id composite, u32 index);
95void EmitCompositeExtractF16x4(EmitContext& ctx); 96Id EmitCompositeExtractF16x4(EmitContext& ctx, Id composite, u32 index);
96void EmitCompositeConstructF32x2(EmitContext& ctx); 97void EmitCompositeConstructF32x2(EmitContext& ctx);
97void EmitCompositeConstructF32x3(EmitContext& ctx); 98void EmitCompositeConstructF32x3(EmitContext& ctx);
98void EmitCompositeConstructF32x4(EmitContext& ctx); 99void EmitCompositeConstructF32x4(EmitContext& ctx);
99void EmitCompositeExtractF32x2(EmitContext& ctx); 100Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index);
100void EmitCompositeExtractF32x3(EmitContext& ctx); 101Id EmitCompositeExtractF32x3(EmitContext& ctx, Id composite, u32 index);
101void EmitCompositeExtractF32x4(EmitContext& ctx); 102Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index);
102void EmitCompositeConstructF64x2(EmitContext& ctx); 103void EmitCompositeConstructF64x2(EmitContext& ctx);
103void EmitCompositeConstructF64x3(EmitContext& ctx); 104void EmitCompositeConstructF64x3(EmitContext& ctx);
104void EmitCompositeConstructF64x4(EmitContext& ctx); 105void EmitCompositeConstructF64x4(EmitContext& ctx);
@@ -116,11 +117,13 @@ void EmitBitCastF16U16(EmitContext& ctx);
116Id EmitBitCastF32U32(EmitContext& ctx, Id value); 117Id EmitBitCastF32U32(EmitContext& ctx, Id value);
117void EmitBitCastF64U64(EmitContext& ctx); 118void EmitBitCastF64U64(EmitContext& ctx);
118void EmitPackUint2x32(EmitContext& ctx); 119void EmitPackUint2x32(EmitContext& ctx);
119void EmitUnpackUint2x32(EmitContext& ctx); 120Id EmitUnpackUint2x32(EmitContext& ctx, Id value);
120void EmitPackFloat2x16(EmitContext& ctx); 121Id EmitPackFloat2x16(EmitContext& ctx, Id value);
121void EmitUnpackFloat2x16(EmitContext& ctx); 122Id EmitUnpackFloat2x16(EmitContext& ctx, Id value);
122void EmitPackDouble2x32(EmitContext& ctx); 123Id EmitPackHalf2x16(EmitContext& ctx, Id value);
123void EmitUnpackDouble2x32(EmitContext& ctx); 124Id EmitUnpackHalf2x16(EmitContext& ctx, Id value);
125Id EmitPackDouble2x32(EmitContext& ctx, Id value);
126Id EmitUnpackDouble2x32(EmitContext& ctx, Id value);
124void EmitGetZeroFromOp(EmitContext& ctx); 127void EmitGetZeroFromOp(EmitContext& ctx);
125void EmitGetSignFromOp(EmitContext& ctx); 128void EmitGetSignFromOp(EmitContext& ctx);
126void EmitGetCarryFromOp(EmitContext& ctx); 129void EmitGetCarryFromOp(EmitContext& ctx);
@@ -159,18 +162,18 @@ void EmitFPLog2(EmitContext& ctx);
159void EmitFPSaturate16(EmitContext& ctx); 162void EmitFPSaturate16(EmitContext& ctx);
160void EmitFPSaturate32(EmitContext& ctx); 163void EmitFPSaturate32(EmitContext& ctx);
161void EmitFPSaturate64(EmitContext& ctx); 164void EmitFPSaturate64(EmitContext& ctx);
162void EmitFPRoundEven16(EmitContext& ctx); 165Id EmitFPRoundEven16(EmitContext& ctx, Id value);
163void EmitFPRoundEven32(EmitContext& ctx); 166Id EmitFPRoundEven32(EmitContext& ctx, Id value);
164void EmitFPRoundEven64(EmitContext& ctx); 167Id EmitFPRoundEven64(EmitContext& ctx, Id value);
165void EmitFPFloor16(EmitContext& ctx); 168Id EmitFPFloor16(EmitContext& ctx, Id value);
166void EmitFPFloor32(EmitContext& ctx); 169Id EmitFPFloor32(EmitContext& ctx, Id value);
167void EmitFPFloor64(EmitContext& ctx); 170Id EmitFPFloor64(EmitContext& ctx, Id value);
168void EmitFPCeil16(EmitContext& ctx); 171Id EmitFPCeil16(EmitContext& ctx, Id value);
169void EmitFPCeil32(EmitContext& ctx); 172Id EmitFPCeil32(EmitContext& ctx, Id value);
170void EmitFPCeil64(EmitContext& ctx); 173Id EmitFPCeil64(EmitContext& ctx, Id value);
171void EmitFPTrunc16(EmitContext& ctx); 174Id EmitFPTrunc16(EmitContext& ctx, Id value);
172void EmitFPTrunc32(EmitContext& ctx); 175Id EmitFPTrunc32(EmitContext& ctx, Id value);
173void EmitFPTrunc64(EmitContext& ctx); 176Id EmitFPTrunc64(EmitContext& ctx, Id value);
174Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); 177Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
175void EmitIAdd64(EmitContext& ctx); 178void EmitIAdd64(EmitContext& ctx);
176Id EmitISub32(EmitContext& ctx, Id a, Id b); 179Id EmitISub32(EmitContext& ctx, Id a, Id b);
@@ -201,25 +204,25 @@ void EmitLogicalOr(EmitContext& ctx);
201void EmitLogicalAnd(EmitContext& ctx); 204void EmitLogicalAnd(EmitContext& ctx);
202void EmitLogicalXor(EmitContext& ctx); 205void EmitLogicalXor(EmitContext& ctx);
203void EmitLogicalNot(EmitContext& ctx); 206void EmitLogicalNot(EmitContext& ctx);
204void EmitConvertS16F16(EmitContext& ctx); 207Id EmitConvertS16F16(EmitContext& ctx, Id value);
205void EmitConvertS16F32(EmitContext& ctx); 208Id EmitConvertS16F32(EmitContext& ctx, Id value);
206void EmitConvertS16F64(EmitContext& ctx); 209Id EmitConvertS16F64(EmitContext& ctx, Id value);
207void EmitConvertS32F16(EmitContext& ctx); 210Id EmitConvertS32F16(EmitContext& ctx, Id value);
208void EmitConvertS32F32(EmitContext& ctx); 211Id EmitConvertS32F32(EmitContext& ctx, Id value);
209void EmitConvertS32F64(EmitContext& ctx); 212Id EmitConvertS32F64(EmitContext& ctx, Id value);
210void EmitConvertS64F16(EmitContext& ctx); 213Id EmitConvertS64F16(EmitContext& ctx, Id value);
211void EmitConvertS64F32(EmitContext& ctx); 214Id EmitConvertS64F32(EmitContext& ctx, Id value);
212void EmitConvertS64F64(EmitContext& ctx); 215Id EmitConvertS64F64(EmitContext& ctx, Id value);
213void EmitConvertU16F16(EmitContext& ctx); 216Id EmitConvertU16F16(EmitContext& ctx, Id value);
214void EmitConvertU16F32(EmitContext& ctx); 217Id EmitConvertU16F32(EmitContext& ctx, Id value);
215void EmitConvertU16F64(EmitContext& ctx); 218Id EmitConvertU16F64(EmitContext& ctx, Id value);
216void EmitConvertU32F16(EmitContext& ctx); 219Id EmitConvertU32F16(EmitContext& ctx, Id value);
217void EmitConvertU32F32(EmitContext& ctx); 220Id EmitConvertU32F32(EmitContext& ctx, Id value);
218void EmitConvertU32F64(EmitContext& ctx); 221Id EmitConvertU32F64(EmitContext& ctx, Id value);
219void EmitConvertU64F16(EmitContext& ctx); 222Id EmitConvertU64F16(EmitContext& ctx, Id value);
220void EmitConvertU64F32(EmitContext& ctx); 223Id EmitConvertU64F32(EmitContext& ctx, Id value);
221void EmitConvertU64F64(EmitContext& ctx); 224Id EmitConvertU64F64(EmitContext& ctx, Id value);
222void EmitConvertU64U32(EmitContext& ctx); 225Id EmitConvertU64U32(EmitContext& ctx, Id value);
223void EmitConvertU32U64(EmitContext& ctx); 226Id EmitConvertU32U64(EmitContext& ctx, Id value);
224 227
225} // namespace Shader::Backend::SPIRV 228} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp
index 49c200498..e0d1ba413 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp
@@ -34,24 +34,32 @@ void EmitPackUint2x32(EmitContext&) {
34 throw NotImplementedException("SPIR-V Instruction"); 34 throw NotImplementedException("SPIR-V Instruction");
35} 35}
36 36
37void EmitUnpackUint2x32(EmitContext&) { 37Id EmitUnpackUint2x32(EmitContext& ctx, Id value) {
38 throw NotImplementedException("SPIR-V Instruction"); 38 return ctx.OpBitcast(ctx.U32[2], value);
39} 39}
40 40
41void EmitPackFloat2x16(EmitContext&) { 41Id EmitPackFloat2x16(EmitContext& ctx, Id value) {
42 throw NotImplementedException("SPIR-V Instruction"); 42 return ctx.OpBitcast(ctx.U32[1], value);
43} 43}
44 44
45void EmitUnpackFloat2x16(EmitContext&) { 45Id EmitUnpackFloat2x16(EmitContext& ctx, Id value) {
46 throw NotImplementedException("SPIR-V Instruction"); 46 return ctx.OpBitcast(ctx.F16[2], value);
47} 47}
48 48
49void EmitPackDouble2x32(EmitContext&) { 49Id EmitPackHalf2x16(EmitContext& ctx, Id value) {
50 throw NotImplementedException("SPIR-V Instruction"); 50 return ctx.OpPackHalf2x16(ctx.U32[1], value);
51} 51}
52 52
53void EmitUnpackDouble2x32(EmitContext&) { 53Id EmitUnpackHalf2x16(EmitContext& ctx, Id value) {
54 throw NotImplementedException("SPIR-V Instruction"); 54 return ctx.OpUnpackHalf2x16(ctx.F32[2], value);
55}
56
57Id EmitPackDouble2x32(EmitContext& ctx, Id value) {
58 return ctx.OpBitcast(ctx.F64[1], value);
59}
60
61Id EmitUnpackDouble2x32(EmitContext& ctx, Id value) {
62 return ctx.OpBitcast(ctx.U32[2], value);
55} 63}
56 64
57} // namespace Shader::Backend::SPIRV 65} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
index 348e4796d..c950854a0 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
@@ -6,28 +6,28 @@
6 6
7namespace Shader::Backend::SPIRV { 7namespace Shader::Backend::SPIRV {
8 8
9void EmitCompositeConstructU32x2(EmitContext&) { 9Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2) {
10 throw NotImplementedException("SPIR-V Instruction"); 10 return ctx.OpCompositeConstruct(ctx.U32[2], e1, e2);
11} 11}
12 12
13void EmitCompositeConstructU32x3(EmitContext&) { 13Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3) {
14 throw NotImplementedException("SPIR-V Instruction"); 14 return ctx.OpCompositeConstruct(ctx.U32[3], e1, e2, e3);
15} 15}
16 16
17void EmitCompositeConstructU32x4(EmitContext&) { 17Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4) {
18 throw NotImplementedException("SPIR-V Instruction"); 18 return ctx.OpCompositeConstruct(ctx.U32[4], e1, e2, e3, e4);
19} 19}
20 20
21void EmitCompositeExtractU32x2(EmitContext&) { 21Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index) {
22 throw NotImplementedException("SPIR-V Instruction"); 22 return ctx.OpCompositeExtract(ctx.U32[1], composite, index);
23} 23}
24 24
25Id EmitCompositeExtractU32x3(EmitContext& ctx, Id vector, u32 index) { 25Id EmitCompositeExtractU32x3(EmitContext& ctx, Id composite, u32 index) {
26 return ctx.OpCompositeExtract(ctx.U32[1], vector, index); 26 return ctx.OpCompositeExtract(ctx.U32[1], composite, index);
27} 27}
28 28
29void EmitCompositeExtractU32x4(EmitContext&) { 29Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index) {
30 throw NotImplementedException("SPIR-V Instruction"); 30 return ctx.OpCompositeExtract(ctx.U32[1], composite, index);
31} 31}
32 32
33void EmitCompositeConstructF16x2(EmitContext&) { 33void EmitCompositeConstructF16x2(EmitContext&) {
@@ -42,16 +42,16 @@ void EmitCompositeConstructF16x4(EmitContext&) {
42 throw NotImplementedException("SPIR-V Instruction"); 42 throw NotImplementedException("SPIR-V Instruction");
43} 43}
44 44
45void EmitCompositeExtractF16x2(EmitContext&) { 45Id EmitCompositeExtractF16x2(EmitContext& ctx, Id composite, u32 index) {
46 throw NotImplementedException("SPIR-V Instruction"); 46 return ctx.OpCompositeExtract(ctx.F16[1], composite, index);
47} 47}
48 48
49void EmitCompositeExtractF16x3(EmitContext&) { 49Id EmitCompositeExtractF16x3(EmitContext& ctx, Id composite, u32 index) {
50 throw NotImplementedException("SPIR-V Instruction"); 50 return ctx.OpCompositeExtract(ctx.F16[1], composite, index);
51} 51}
52 52
53void EmitCompositeExtractF16x4(EmitContext&) { 53Id EmitCompositeExtractF16x4(EmitContext& ctx, Id composite, u32 index) {
54 throw NotImplementedException("SPIR-V Instruction"); 54 return ctx.OpCompositeExtract(ctx.F16[1], composite, index);
55} 55}
56 56
57void EmitCompositeConstructF32x2(EmitContext&) { 57void EmitCompositeConstructF32x2(EmitContext&) {
@@ -66,16 +66,16 @@ void EmitCompositeConstructF32x4(EmitContext&) {
66 throw NotImplementedException("SPIR-V Instruction"); 66 throw NotImplementedException("SPIR-V Instruction");
67} 67}
68 68
69void EmitCompositeExtractF32x2(EmitContext&) { 69Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index) {
70 throw NotImplementedException("SPIR-V Instruction"); 70 return ctx.OpCompositeExtract(ctx.F32[1], composite, index);
71} 71}
72 72
73void EmitCompositeExtractF32x3(EmitContext&) { 73Id EmitCompositeExtractF32x3(EmitContext& ctx, Id composite, u32 index) {
74 throw NotImplementedException("SPIR-V Instruction"); 74 return ctx.OpCompositeExtract(ctx.F32[1], composite, index);
75} 75}
76 76
77void EmitCompositeExtractF32x4(EmitContext&) { 77Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index) {
78 throw NotImplementedException("SPIR-V Instruction"); 78 return ctx.OpCompositeExtract(ctx.F32[1], composite, index);
79} 79}
80 80
81void EmitCompositeConstructF64x2(EmitContext&) { 81void EmitCompositeConstructF64x2(EmitContext&) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
index 6c4199664..48755b827 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
@@ -11,7 +11,7 @@ void EmitBranch(EmitContext& ctx, IR::Block* label) {
11} 11}
12 12
13void EmitBranchConditional(EmitContext& ctx, Id condition, IR::Block* true_label, 13void EmitBranchConditional(EmitContext& ctx, Id condition, IR::Block* true_label,
14 IR::Block* false_label) { 14 IR::Block* false_label) {
15 ctx.OpBranchConditional(condition, true_label->Definition<Id>(), false_label->Definition<Id>()); 15 ctx.OpBranchConditional(condition, true_label->Definition<Id>(), false_label->Definition<Id>());
16} 16}
17 17
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp
new file mode 100644
index 000000000..76ccaffce
--- /dev/null
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp
@@ -0,0 +1,89 @@
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/backend/spirv/emit_spirv.h"
6
7namespace Shader::Backend::SPIRV {
8
9Id EmitConvertS16F16(EmitContext& ctx, Id value) {
10 return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value));
11}
12
13Id EmitConvertS16F32(EmitContext& ctx, Id value) {
14 return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value));
15}
16
17Id EmitConvertS16F64(EmitContext& ctx, Id value) {
18 return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value));
19}
20
21Id EmitConvertS32F16(EmitContext& ctx, Id value) {
22 return ctx.OpConvertFToS(ctx.U32[1], value);
23}
24
25Id EmitConvertS32F32(EmitContext& ctx, Id value) {
26 return ctx.OpConvertFToS(ctx.U32[1], value);
27}
28
29Id EmitConvertS32F64(EmitContext& ctx, Id value) {
30 return ctx.OpConvertFToS(ctx.U32[1], value);
31}
32
33Id EmitConvertS64F16(EmitContext& ctx, Id value) {
34 return ctx.OpConvertFToS(ctx.U64, value);
35}
36
37Id EmitConvertS64F32(EmitContext& ctx, Id value) {
38 return ctx.OpConvertFToS(ctx.U64, value);
39}
40
41Id EmitConvertS64F64(EmitContext& ctx, Id value) {
42 return ctx.OpConvertFToS(ctx.U64, value);
43}
44
45Id EmitConvertU16F16(EmitContext& ctx, Id value) {
46 return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value));
47}
48
49Id EmitConvertU16F32(EmitContext& ctx, Id value) {
50 return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value));
51}
52
53Id EmitConvertU16F64(EmitContext& ctx, Id value) {
54 return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value));
55}
56
57Id EmitConvertU32F16(EmitContext& ctx, Id value) {
58 return ctx.OpConvertFToU(ctx.U32[1], value);
59}
60
61Id EmitConvertU32F32(EmitContext& ctx, Id value) {
62 return ctx.OpConvertFToU(ctx.U32[1], value);
63}
64
65Id EmitConvertU32F64(EmitContext& ctx, Id value) {
66 return ctx.OpConvertFToU(ctx.U32[1], value);
67}
68
69Id EmitConvertU64F16(EmitContext& ctx, Id value) {
70 return ctx.OpConvertFToU(ctx.U64, value);
71}
72
73Id EmitConvertU64F32(EmitContext& ctx, Id value) {
74 return ctx.OpConvertFToU(ctx.U64, value);
75}
76
77Id EmitConvertU64F64(EmitContext& ctx, Id value) {
78 return ctx.OpConvertFToU(ctx.U64, value);
79}
80
81Id EmitConvertU64U32(EmitContext& ctx, Id value) {
82 return ctx.OpUConvert(ctx.U64, value);
83}
84
85Id EmitConvertU32U64(EmitContext& ctx, Id value) {
86 return ctx.OpUConvert(ctx.U32[1], value);
87}
88
89} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp
index d24fbb353..9ef180531 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp
@@ -169,52 +169,52 @@ void EmitFPSaturate64(EmitContext&) {
169 throw NotImplementedException("SPIR-V Instruction"); 169 throw NotImplementedException("SPIR-V Instruction");
170} 170}
171 171
172void EmitFPRoundEven16(EmitContext&) { 172Id EmitFPRoundEven16(EmitContext& ctx, Id value) {
173 throw NotImplementedException("SPIR-V Instruction"); 173 return ctx.OpRoundEven(ctx.F16[1], value);
174} 174}
175 175
176void EmitFPRoundEven32(EmitContext&) { 176Id EmitFPRoundEven32(EmitContext& ctx, Id value) {
177 throw NotImplementedException("SPIR-V Instruction"); 177 return ctx.OpRoundEven(ctx.F32[1], value);
178} 178}
179 179
180void EmitFPRoundEven64(EmitContext&) { 180Id EmitFPRoundEven64(EmitContext& ctx, Id value) {
181 throw NotImplementedException("SPIR-V Instruction"); 181 return ctx.OpRoundEven(ctx.F64[1], value);
182} 182}
183 183
184void EmitFPFloor16(EmitContext&) { 184Id EmitFPFloor16(EmitContext& ctx, Id value) {
185 throw NotImplementedException("SPIR-V Instruction"); 185 return ctx.OpFloor(ctx.F16[1], value);
186} 186}
187 187
188void EmitFPFloor32(EmitContext&) { 188Id EmitFPFloor32(EmitContext& ctx, Id value) {
189 throw NotImplementedException("SPIR-V Instruction"); 189 return ctx.OpFloor(ctx.F32[1], value);
190} 190}
191 191
192void EmitFPFloor64(EmitContext&) { 192Id EmitFPFloor64(EmitContext& ctx, Id value) {
193 throw NotImplementedException("SPIR-V Instruction"); 193 return ctx.OpFloor(ctx.F64[1], value);
194} 194}
195 195
196void EmitFPCeil16(EmitContext&) { 196Id EmitFPCeil16(EmitContext& ctx, Id value) {
197 throw NotImplementedException("SPIR-V Instruction"); 197 return ctx.OpCeil(ctx.F16[1], value);
198} 198}
199 199
200void EmitFPCeil32(EmitContext&) { 200Id EmitFPCeil32(EmitContext& ctx, Id value) {
201 throw NotImplementedException("SPIR-V Instruction"); 201 return ctx.OpCeil(ctx.F32[1], value);
202} 202}
203 203
204void EmitFPCeil64(EmitContext&) { 204Id EmitFPCeil64(EmitContext& ctx, Id value) {
205 throw NotImplementedException("SPIR-V Instruction"); 205 return ctx.OpCeil(ctx.F64[1], value);
206} 206}
207 207
208void EmitFPTrunc16(EmitContext&) { 208Id EmitFPTrunc16(EmitContext& ctx, Id value) {
209 throw NotImplementedException("SPIR-V Instruction"); 209 return ctx.OpTrunc(ctx.F16[1], value);
210} 210}
211 211
212void EmitFPTrunc32(EmitContext&) { 212Id EmitFPTrunc32(EmitContext& ctx, Id value) {
213 throw NotImplementedException("SPIR-V Instruction"); 213 return ctx.OpTrunc(ctx.F32[1], value);
214} 214}
215 215
216void EmitFPTrunc64(EmitContext&) { 216Id EmitFPTrunc64(EmitContext& ctx, Id value) {
217 throw NotImplementedException("SPIR-V Instruction"); 217 return ctx.OpTrunc(ctx.F64[1], value);
218} 218}
219 219
220} // namespace Shader::Backend::SPIRV 220} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
index a1d16b81e..22117a4ee 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
@@ -113,20 +113,4 @@ Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
113 return ctx.OpUGreaterThanEqual(ctx.U1, lhs, rhs); 113 return ctx.OpUGreaterThanEqual(ctx.U1, lhs, rhs);
114} 114}
115 115
116void EmitLogicalOr(EmitContext&) {
117 throw NotImplementedException("SPIR-V Instruction");
118}
119
120void EmitLogicalAnd(EmitContext&) {
121 throw NotImplementedException("SPIR-V Instruction");
122}
123
124void EmitLogicalXor(EmitContext&) {
125 throw NotImplementedException("SPIR-V Instruction");
126}
127
128void EmitLogicalNot(EmitContext&) {
129 throw NotImplementedException("SPIR-V Instruction");
130}
131
132} // namespace Shader::Backend::SPIRV 116} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
index ff2f4fb74..c5a07252f 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
@@ -6,83 +6,19 @@
6 6
7namespace Shader::Backend::SPIRV { 7namespace Shader::Backend::SPIRV {
8 8
9void EmitConvertS16F16(EmitContext&) { 9void EmitLogicalOr(EmitContext&) {
10 throw NotImplementedException("SPIR-V Instruction"); 10 throw NotImplementedException("SPIR-V Instruction");
11} 11}
12 12
13void EmitConvertS16F32(EmitContext&) { 13void EmitLogicalAnd(EmitContext&) {
14 throw NotImplementedException("SPIR-V Instruction"); 14 throw NotImplementedException("SPIR-V Instruction");
15} 15}
16 16
17void EmitConvertS16F64(EmitContext&) { 17void EmitLogicalXor(EmitContext&) {
18 throw NotImplementedException("SPIR-V Instruction"); 18 throw NotImplementedException("SPIR-V Instruction");
19} 19}
20 20
21void EmitConvertS32F16(EmitContext&) { 21void EmitLogicalNot(EmitContext&) {
22 throw NotImplementedException("SPIR-V Instruction");
23}
24
25void EmitConvertS32F32(EmitContext&) {
26 throw NotImplementedException("SPIR-V Instruction");
27}
28
29void EmitConvertS32F64(EmitContext&) {
30 throw NotImplementedException("SPIR-V Instruction");
31}
32
33void EmitConvertS64F16(EmitContext&) {
34 throw NotImplementedException("SPIR-V Instruction");
35}
36
37void EmitConvertS64F32(EmitContext&) {
38 throw NotImplementedException("SPIR-V Instruction");
39}
40
41void EmitConvertS64F64(EmitContext&) {
42 throw NotImplementedException("SPIR-V Instruction");
43}
44
45void EmitConvertU16F16(EmitContext&) {
46 throw NotImplementedException("SPIR-V Instruction");
47}
48
49void EmitConvertU16F32(EmitContext&) {
50 throw NotImplementedException("SPIR-V Instruction");
51}
52
53void EmitConvertU16F64(EmitContext&) {
54 throw NotImplementedException("SPIR-V Instruction");
55}
56
57void EmitConvertU32F16(EmitContext&) {
58 throw NotImplementedException("SPIR-V Instruction");
59}
60
61void EmitConvertU32F32(EmitContext&) {
62 throw NotImplementedException("SPIR-V Instruction");
63}
64
65void EmitConvertU32F64(EmitContext&) {
66 throw NotImplementedException("SPIR-V Instruction");
67}
68
69void EmitConvertU64F16(EmitContext&) {
70 throw NotImplementedException("SPIR-V Instruction");
71}
72
73void EmitConvertU64F32(EmitContext&) {
74 throw NotImplementedException("SPIR-V Instruction");
75}
76
77void EmitConvertU64F64(EmitContext&) {
78 throw NotImplementedException("SPIR-V Instruction");
79}
80
81void EmitConvertU64U32(EmitContext&) {
82 throw NotImplementedException("SPIR-V Instruction");
83}
84
85void EmitConvertU32U64(EmitContext&) {
86 throw NotImplementedException("SPIR-V Instruction"); 22 throw NotImplementedException("SPIR-V Instruction");
87} 23}
88 24
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
index 77d698ffd..808c1b401 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp
@@ -94,8 +94,7 @@ void EmitLoadStorageS16(EmitContext&) {
94 throw NotImplementedException("SPIR-V Instruction"); 94 throw NotImplementedException("SPIR-V Instruction");
95} 95}
96 96
97Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, 97Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
98 const IR::Value& offset) {
99 if (!binding.IsImmediate()) { 98 if (!binding.IsImmediate()) {
100 throw NotImplementedException("Dynamic storage buffer indexing"); 99 throw NotImplementedException("Dynamic storage buffer indexing");
101 } 100 }
@@ -129,8 +128,8 @@ void EmitWriteStorageS16(EmitContext&) {
129 throw NotImplementedException("SPIR-V Instruction"); 128 throw NotImplementedException("SPIR-V Instruction");
130} 129}
131 130
132void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, 131void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
133 const IR::Value& offset, Id value) { 132 Id value) {
134 if (!binding.IsImmediate()) { 133 if (!binding.IsImmediate()) {
135 throw NotImplementedException("Dynamic storage buffer indexing"); 134 throw NotImplementedException("Dynamic storage buffer indexing");
136 } 135 }
@@ -140,8 +139,19 @@ void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding,
140 ctx.OpStore(pointer, value); 139 ctx.OpStore(pointer, value);
141} 140}
142 141
143void EmitWriteStorage64(EmitContext&) { 142void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
144 throw NotImplementedException("SPIR-V Instruction"); 143 Id value) {
144 if (!binding.IsImmediate()) {
145 throw NotImplementedException("Dynamic storage buffer indexing");
146 }
147 // TODO: Support reinterpreting bindings, guaranteed to be aligned
148 const Id ssbo{ctx.ssbos[binding.U32()]};
149 const Id low_index{StorageIndex(ctx, offset, sizeof(u32))};
150 const Id high_index{ctx.OpIAdd(ctx.U32[1], low_index, ctx.Constant(ctx.U32[1], 1U))};
151 const Id low_pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, low_index)};
152 const Id high_pointer{ctx.OpAccessChain(ctx.storage_u32, ssbo, ctx.u32_zero_value, high_index)};
153 ctx.OpStore(low_pointer, ctx.OpCompositeExtract(ctx.U32[1], value, 0U));
154 ctx.OpStore(high_pointer, ctx.OpCompositeExtract(ctx.U32[1], value, 1U));
145} 155}
146 156
147void EmitWriteStorage128(EmitContext&) { 157void EmitWriteStorage128(EmitContext&) {