summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h17
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp63
3 files changed, 67 insertions, 21 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index 528dc33fe..9db2b0c94 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -97,6 +97,23 @@ public:
97 97
98 [[nodiscard]] Id Def(const IR::Value& value); 98 [[nodiscard]] Id Def(const IR::Value& value);
99 99
100 Id Const(u32 value) {
101 return Constant(U32[1], value);
102 }
103
104 Id Const(u32 element_1, u32 element_2) {
105 return ConstantComposite(U32[2], Const(element_1), Const(element_2));
106 }
107
108 Id Const(u32 element_1, u32 element_2, u32 element_3) {
109 return ConstantComposite(U32[3], Const(element_1), Const(element_2), Const(element_3));
110 }
111
112 Id Const(u32 element_1, u32 element_2, u32 element_3, u32 element_4) {
113 return ConstantComposite(U32[2], Const(element_1), Const(element_2), Const(element_3),
114 Const(element_4));
115 }
116
100 const Profile& profile; 117 const Profile& profile;
101 Stage stage{}; 118 Stage stage{};
102 119
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 9f658a4bd..cf8d74f4e 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -490,13 +490,13 @@ Id EmitBoundImageGradient(EmitContext&);
490Id EmitBoundImageRead(EmitContext&); 490Id EmitBoundImageRead(EmitContext&);
491Id EmitBoundImageWrite(EmitContext&); 491Id EmitBoundImageWrite(EmitContext&);
492Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 492Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
493 Id bias_lc, Id offset); 493 Id bias_lc, const IR::Value& offset);
494Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 494Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
495 Id lod_lc, Id offset); 495 Id lod_lc, const IR::Value& offset);
496Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 496Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
497 Id coords, Id dref, Id bias_lc, Id offset); 497 Id coords, Id dref, Id bias_lc, const IR::Value& offset);
498Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 498Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
499 Id coords, Id dref, Id lod_lc, Id offset); 499 Id coords, Id dref, Id lod_lc, const IR::Value& offset);
500Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 500Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
501 const IR::Value& offset, const IR::Value& offset2); 501 const IR::Value& offset, const IR::Value& offset2);
502Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 502Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index c8d1d25b1..021933a8c 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -12,7 +12,7 @@ namespace {
12class ImageOperands { 12class ImageOperands {
13public: 13public:
14 explicit ImageOperands(EmitContext& ctx, bool has_bias, bool has_lod, bool has_lod_clamp, 14 explicit ImageOperands(EmitContext& ctx, bool has_bias, bool has_lod, bool has_lod_clamp,
15 Id lod, Id offset) { 15 Id lod, const IR::Value& offset) {
16 if (has_bias) { 16 if (has_bias) {
17 const Id bias{has_lod_clamp ? ctx.OpCompositeExtract(ctx.F32[1], lod, 0) : lod}; 17 const Id bias{has_lod_clamp ? ctx.OpCompositeExtract(ctx.F32[1], lod, 0) : lod};
18 Add(spv::ImageOperandsMask::Bias, bias); 18 Add(spv::ImageOperandsMask::Bias, bias);
@@ -21,9 +21,7 @@ public:
21 const Id lod_value{has_lod_clamp ? ctx.OpCompositeExtract(ctx.F32[1], lod, 0) : lod}; 21 const Id lod_value{has_lod_clamp ? ctx.OpCompositeExtract(ctx.F32[1], lod, 0) : lod};
22 Add(spv::ImageOperandsMask::Lod, lod_value); 22 Add(spv::ImageOperandsMask::Lod, lod_value);
23 } 23 }
24 if (Sirit::ValidId(offset)) { 24 AddOffset(ctx, offset);
25 Add(spv::ImageOperandsMask::Offset, offset);
26 }
27 if (has_lod_clamp) { 25 if (has_lod_clamp) {
28 const Id lod_clamp{has_bias ? ctx.OpCompositeExtract(ctx.F32[1], lod, 1) : lod}; 26 const Id lod_clamp{has_bias ? ctx.OpCompositeExtract(ctx.F32[1], lod, 1) : lod};
29 Add(spv::ImageOperandsMask::MinLod, lod_clamp); 27 Add(spv::ImageOperandsMask::MinLod, lod_clamp);
@@ -96,6 +94,46 @@ public:
96 } 94 }
97 } 95 }
98 96
97 std::span<const Id> Span() const noexcept {
98 return std::span{operands.data(), operands.size()};
99 }
100
101 spv::ImageOperandsMask Mask() const noexcept {
102 return mask;
103 }
104
105private:
106 void AddOffset(EmitContext& ctx, const IR::Value& offset) {
107 if (offset.IsEmpty()) {
108 return;
109 }
110 if (offset.IsImmediate()) {
111 Add(spv::ImageOperandsMask::ConstOffset, ctx.Constant(ctx.U32[1], offset.U32()));
112 return;
113 }
114 IR::Inst* const inst{offset.InstRecursive()};
115 if (inst->AreAllArgsImmediates()) {
116 switch (inst->GetOpcode()) {
117 case IR::Opcode::CompositeConstructU32x2:
118 Add(spv::ImageOperandsMask::ConstOffset,
119 ctx.Const(inst->Arg(0).U32(), inst->Arg(1).U32()));
120 return;
121 case IR::Opcode::CompositeConstructU32x3:
122 Add(spv::ImageOperandsMask::ConstOffset,
123 ctx.Const(inst->Arg(0).U32(), inst->Arg(1).U32(), inst->Arg(2).U32()));
124 return;
125 case IR::Opcode::CompositeConstructU32x4:
126 Add(spv::ImageOperandsMask::ConstOffset,
127 ctx.Const(inst->Arg(0).U32(), inst->Arg(1).U32(), inst->Arg(2).U32(),
128 inst->Arg(3).U32()));
129 return;
130 default:
131 break;
132 }
133 }
134 Add(spv::ImageOperandsMask::Offset, ctx.Def(offset));
135 }
136
99 void Add(spv::ImageOperandsMask new_mask, Id value) { 137 void Add(spv::ImageOperandsMask new_mask, Id value) {
100 mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) | 138 mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) |
101 static_cast<unsigned>(new_mask)); 139 static_cast<unsigned>(new_mask));
@@ -109,15 +147,6 @@ public:
109 operands.push_back(value_2); 147 operands.push_back(value_2);
110 } 148 }
111 149
112 std::span<const Id> Span() const noexcept {
113 return std::span{operands.data(), operands.size()};
114 }
115
116 spv::ImageOperandsMask Mask() const noexcept {
117 return mask;
118 }
119
120private:
121 boost::container::static_vector<Id, 4> operands; 150 boost::container::static_vector<Id, 4> operands;
122 spv::ImageOperandsMask mask{}; 151 spv::ImageOperandsMask mask{};
123}; 152};
@@ -279,7 +308,7 @@ Id EmitBoundImageWrite(EmitContext&) {
279} 308}
280 309
281Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 310Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
282 Id bias_lc, Id offset) { 311 Id bias_lc, const IR::Value& offset) {
283 const auto info{inst->Flags<IR::TextureInstInfo>()}; 312 const auto info{inst->Flags<IR::TextureInstInfo>()};
284 const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, bias_lc, 313 const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, bias_lc,
285 offset); 314 offset);
@@ -289,7 +318,7 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
289} 318}
290 319
291Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 320Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
292 Id lod_lc, Id offset) { 321 Id lod_lc, const IR::Value& offset) {
293 const auto info{inst->Flags<IR::TextureInstInfo>()}; 322 const auto info{inst->Flags<IR::TextureInstInfo>()};
294 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset); 323 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset);
295 return Emit(&EmitContext::OpImageSparseSampleExplicitLod, 324 return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
@@ -298,7 +327,7 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
298} 327}
299 328
300Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 329Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
301 Id coords, Id dref, Id bias_lc, Id offset) { 330 Id coords, Id dref, Id bias_lc, const IR::Value& offset) {
302 const auto info{inst->Flags<IR::TextureInstInfo>()}; 331 const auto info{inst->Flags<IR::TextureInstInfo>()};
303 const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, bias_lc, 332 const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, bias_lc,
304 offset); 333 offset);
@@ -308,7 +337,7 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
308} 337}
309 338
310Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 339Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
311 Id coords, Id dref, Id lod_lc, Id offset) { 340 Id coords, Id dref, Id lod_lc, const IR::Value& offset) {
312 const auto info{inst->Flags<IR::TextureInstInfo>()}; 341 const auto info{inst->Flags<IR::TextureInstInfo>()};
313 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset); 342 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset);
314 return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod, 343 return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod,