summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp32
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp6
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h8
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc3
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp5
7 files changed, 55 insertions, 5 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index eaf94dad5..cc02f53f1 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -343,12 +343,14 @@ Id EmitBindlessImageSampleDrefImplicitLod(EmitContext&);
343Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&); 343Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&);
344Id EmitBindlessImageGather(EmitContext&); 344Id EmitBindlessImageGather(EmitContext&);
345Id EmitBindlessImageGatherDref(EmitContext&); 345Id EmitBindlessImageGatherDref(EmitContext&);
346Id EmitBindlessImageFetch(EmitContext&);
346Id EmitBoundImageSampleImplicitLod(EmitContext&); 347Id EmitBoundImageSampleImplicitLod(EmitContext&);
347Id EmitBoundImageSampleExplicitLod(EmitContext&); 348Id EmitBoundImageSampleExplicitLod(EmitContext&);
348Id EmitBoundImageSampleDrefImplicitLod(EmitContext&); 349Id EmitBoundImageSampleDrefImplicitLod(EmitContext&);
349Id EmitBoundImageSampleDrefExplicitLod(EmitContext&); 350Id EmitBoundImageSampleDrefExplicitLod(EmitContext&);
350Id EmitBoundImageGather(EmitContext&); 351Id EmitBoundImageGather(EmitContext&);
351Id EmitBoundImageGatherDref(EmitContext&); 352Id EmitBoundImageGatherDref(EmitContext&);
353Id EmitBoundImageFetch(EmitContext&);
352Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 354Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
353 Id bias_lc, Id offset); 355 Id bias_lc, Id offset);
354Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 356Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
@@ -361,6 +363,8 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id
361 Id offset2); 363 Id offset2);
362Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 364Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
363 Id offset, Id offset2, Id dref); 365 Id offset, Id offset2, Id dref);
366Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
367 Id lod, Id ms);
364Id EmitVoteAll(EmitContext& ctx, Id pred); 368Id EmitVoteAll(EmitContext& ctx, Id pred);
365Id EmitVoteAny(EmitContext& ctx, Id pred); 369Id EmitVoteAny(EmitContext& ctx, Id pred);
366Id EmitVoteEqual(EmitContext& ctx, Id pred); 370Id EmitVoteEqual(EmitContext& ctx, Id pred);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
index 0da682859..f01d69d91 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp
@@ -170,7 +170,7 @@ Id EmitCompositeConstructArrayU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id
170 return ctx.ConstantComposite(ctx.array_U32x2, e1, e2, e3, e4); 170 return ctx.ConstantComposite(ctx.array_U32x2, e1, e2, e3, e4);
171 } 171 }
172 if (ctx.profile.support_variadic_ptp) { 172 if (ctx.profile.support_variadic_ptp) {
173 return OpCompositeConstruct(ctx.array_U32x2, e1, e2, e3, e4); 173 return ctx.OpCompositeConstruct(ctx.array_U32x2, e1, e2, e3, e4);
174 } 174 }
175 return {}; 175 return {};
176} 176}
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 776afd4ab..13bc8831f 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -39,6 +39,18 @@ public:
39 } 39 }
40 } 40 }
41 41
42 explicit ImageOperands([[maybe_unused]] EmitContext& ctx, Id offset, Id lod, Id ms) {
43 if (Sirit::ValidId(lod)) {
44 Add(spv::ImageOperandsMask::Lod, lod);
45 }
46 if (Sirit::ValidId(offset)) {
47 Add(spv::ImageOperandsMask::Offset, offset);
48 }
49 if (Sirit::ValidId(ms)) {
50 Add(spv::ImageOperandsMask::Sample, ms);
51 }
52 }
53
42 void Add(spv::ImageOperandsMask new_mask, Id value) { 54 void Add(spv::ImageOperandsMask new_mask, Id value) {
43 mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) | 55 mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) |
44 static_cast<unsigned>(new_mask)); 56 static_cast<unsigned>(new_mask));
@@ -115,6 +127,10 @@ Id EmitBindlessImageGatherDref(EmitContext&) {
115 throw LogicError("Unreachable instruction"); 127 throw LogicError("Unreachable instruction");
116} 128}
117 129
130Id EmitBindlessImageFetch(EmitContext&) {
131 throw LogicError("Unreachable instruction");
132}
133
118Id EmitBoundImageSampleImplicitLod(EmitContext&) { 134Id EmitBoundImageSampleImplicitLod(EmitContext&) {
119 throw LogicError("Unreachable instruction"); 135 throw LogicError("Unreachable instruction");
120} 136}
@@ -139,6 +155,10 @@ Id EmitBoundImageGatherDref(EmitContext&) {
139 throw LogicError("Unreachable instruction"); 155 throw LogicError("Unreachable instruction");
140} 156}
141 157
158Id EmitBoundImageFetch(EmitContext&) {
159 throw LogicError("Unreachable instruction");
160}
161
142Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 162Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
143 Id bias_lc, Id offset) { 163 Id bias_lc, Id offset) {
144 const auto info{inst->Flags<IR::TextureInstInfo>()}; 164 const auto info{inst->Flags<IR::TextureInstInfo>()};
@@ -178,7 +198,7 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
178} 198}
179 199
180Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, 200Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
181 [[maybe_unused]] Id offset2) { 201 Id offset2) {
182 const auto info{inst->Flags<IR::TextureInstInfo>()}; 202 const auto info{inst->Flags<IR::TextureInstInfo>()};
183 const ImageOperands operands(ctx, offset, offset2); 203 const ImageOperands operands(ctx, offset, offset2);
184 return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, 204 return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst,
@@ -188,11 +208,19 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id
188} 208}
189 209
190Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 210Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
191 Id offset, [[maybe_unused]] Id offset2, Id dref) { 211 Id offset, Id offset2, Id dref) {
192 const auto info{inst->Flags<IR::TextureInstInfo>()}; 212 const auto info{inst->Flags<IR::TextureInstInfo>()};
193 const ImageOperands operands(ctx, offset, offset2); 213 const ImageOperands operands(ctx, offset, offset2);
194 return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, 214 return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst,
195 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); 215 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span());
196} 216}
197 217
218Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
219 Id lod, Id ms) {
220 const auto info{inst->Flags<IR::TextureInstInfo>()};
221 const ImageOperands operands(ctx, offset, lod, ms);
222 return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4],
223 Texture(ctx, index), coords, operands.Mask(), operands.Span());
224}
225
198} // namespace Shader::Backend::SPIRV 226} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index f49c30484..b8d36f362 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -1491,6 +1491,12 @@ Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const
1491 return Inst(op, Flags{info}, handle, coords, offset, offset2, dref); 1491 return Inst(op, Flags{info}, handle, coords, offset, offset2, dref);
1492} 1492}
1493 1493
1494Value IREmitter::ImageFetch(const Value& handle, const Value& coords, const Value& offset,
1495 const U32& lod, const U32& multisampling, TextureInstInfo info) {
1496 const Opcode op{handle.IsImmediate() ? Opcode::BoundImageFetch : Opcode::BindlessImageFetch};
1497 return Inst(op, Flags{info}, handle, coords, offset, lod, multisampling);
1498}
1499
1494U1 IREmitter::VoteAll(const U1& value) { 1500U1 IREmitter::VoteAll(const U1& value) {
1495 return Inst<U1>(Opcode::VoteAll, value); 1501 return Inst<U1>(Opcode::VoteAll, value);
1496} 1502}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index 04b43197f..446fd7785 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -243,8 +243,12 @@ public:
243 [[nodiscard]] Value ImageGather(const Value& handle, const Value& coords, const Value& offset, 243 [[nodiscard]] Value ImageGather(const Value& handle, const Value& coords, const Value& offset,
244 const Value& offset2, TextureInstInfo info); 244 const Value& offset2, TextureInstInfo info);
245 245
246 [[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords, const Value& offset, 246 [[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords,
247 const Value& offset2, const F32& dref, TextureInstInfo info); 247 const Value& offset, const Value& offset2, const F32& dref,
248 TextureInstInfo info);
249
250 [[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const Value& offset,
251 const U32& lod, const U32& multisampling, TextureInstInfo info);
248 252
249 [[nodiscard]] U1 VoteAll(const U1& value); 253 [[nodiscard]] U1 VoteAll(const U1& value);
250 [[nodiscard]] U1 VoteAny(const U1& value); 254 [[nodiscard]] U1 VoteAny(const U1& value);
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 0dc0aabdf..3dacd7b6b 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -356,6 +356,7 @@ OPCODE(BindlessImageSampleDrefImplicitLod, F32, U32,
356OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 356OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
357OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) 357OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, )
358OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) 358OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, )
359OPCODE(BindlessImageFetch, F32x4, U32, Opaque, U32, U32, )
359 360
360OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) 361OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, )
361OPCODE(BoundImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) 362OPCODE(BoundImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, )
@@ -363,6 +364,7 @@ OPCODE(BoundImageSampleDrefImplicitLod, F32, U32,
363OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 364OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
364OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) 365OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, )
365OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) 366OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, )
367OPCODE(BoundImageFetch, F32x4, U32, Opaque, U32, U32, )
366 368
367OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) 369OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, )
368OPCODE(ImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) 370OPCODE(ImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, )
@@ -370,6 +372,7 @@ OPCODE(ImageSampleDrefImplicitLod, F32, U32,
370OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 372OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
371OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) 373OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, )
372OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) 374OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, )
375OPCODE(ImageFetch, F32x4, U32, Opaque, U32, U32, )
373 376
374// Warp operations 377// Warp operations
375OPCODE(VoteAll, U1, U1, ) 378OPCODE(VoteAll, U1, U1, )
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index 454ac3e71..0167dd06e 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -51,6 +51,9 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) {
51 case IR::Opcode::BindlessImageGatherDref: 51 case IR::Opcode::BindlessImageGatherDref:
52 case IR::Opcode::BoundImageGatherDref: 52 case IR::Opcode::BoundImageGatherDref:
53 return IR::Opcode::ImageGatherDref; 53 return IR::Opcode::ImageGatherDref;
54 case IR::Opcode::BindlessImageFetch:
55 case IR::Opcode::BoundImageFetch:
56 return IR::Opcode::ImageFetch;
54 default: 57 default:
55 return IR::Opcode::Void; 58 return IR::Opcode::Void;
56 } 59 }
@@ -64,6 +67,7 @@ bool IsBindless(const IR::Inst& inst) {
64 case IR::Opcode::BindlessImageSampleDrefExplicitLod: 67 case IR::Opcode::BindlessImageSampleDrefExplicitLod:
65 case IR::Opcode::BindlessImageGather: 68 case IR::Opcode::BindlessImageGather:
66 case IR::Opcode::BindlessImageGatherDref: 69 case IR::Opcode::BindlessImageGatherDref:
70 case IR::Opcode::BindlessImageFetch:
67 return true; 71 return true;
68 case IR::Opcode::BoundImageSampleImplicitLod: 72 case IR::Opcode::BoundImageSampleImplicitLod:
69 case IR::Opcode::BoundImageSampleExplicitLod: 73 case IR::Opcode::BoundImageSampleExplicitLod:
@@ -71,6 +75,7 @@ bool IsBindless(const IR::Inst& inst) {
71 case IR::Opcode::BoundImageSampleDrefExplicitLod: 75 case IR::Opcode::BoundImageSampleDrefExplicitLod:
72 case IR::Opcode::BoundImageGather: 76 case IR::Opcode::BoundImageGather:
73 case IR::Opcode::BoundImageGatherDref: 77 case IR::Opcode::BoundImageGatherDref:
78 case IR::Opcode::BoundImageFetch:
74 return false; 79 return false;
75 default: 80 default:
76 throw InvalidArgument("Invalid opcode {}", inst.Opcode()); 81 throw InvalidArgument("Invalid opcode {}", inst.Opcode());