diff options
Diffstat (limited to '')
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&); | |||
| 343 | Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&); | 343 | Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&); |
| 344 | Id EmitBindlessImageGather(EmitContext&); | 344 | Id EmitBindlessImageGather(EmitContext&); |
| 345 | Id EmitBindlessImageGatherDref(EmitContext&); | 345 | Id EmitBindlessImageGatherDref(EmitContext&); |
| 346 | Id EmitBindlessImageFetch(EmitContext&); | ||
| 346 | Id EmitBoundImageSampleImplicitLod(EmitContext&); | 347 | Id EmitBoundImageSampleImplicitLod(EmitContext&); |
| 347 | Id EmitBoundImageSampleExplicitLod(EmitContext&); | 348 | Id EmitBoundImageSampleExplicitLod(EmitContext&); |
| 348 | Id EmitBoundImageSampleDrefImplicitLod(EmitContext&); | 349 | Id EmitBoundImageSampleDrefImplicitLod(EmitContext&); |
| 349 | Id EmitBoundImageSampleDrefExplicitLod(EmitContext&); | 350 | Id EmitBoundImageSampleDrefExplicitLod(EmitContext&); |
| 350 | Id EmitBoundImageGather(EmitContext&); | 351 | Id EmitBoundImageGather(EmitContext&); |
| 351 | Id EmitBoundImageGatherDref(EmitContext&); | 352 | Id EmitBoundImageGatherDref(EmitContext&); |
| 353 | Id EmitBoundImageFetch(EmitContext&); | ||
| 352 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 354 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 353 | Id bias_lc, Id offset); | 355 | Id bias_lc, Id offset); |
| 354 | Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 356 | Id 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); |
| 362 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 364 | Id 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); |
| 366 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | ||
| 367 | Id lod, Id ms); | ||
| 364 | Id EmitVoteAll(EmitContext& ctx, Id pred); | 368 | Id EmitVoteAll(EmitContext& ctx, Id pred); |
| 365 | Id EmitVoteAny(EmitContext& ctx, Id pred); | 369 | Id EmitVoteAny(EmitContext& ctx, Id pred); |
| 366 | Id EmitVoteEqual(EmitContext& ctx, Id pred); | 370 | Id 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 | ||
| 130 | Id EmitBindlessImageFetch(EmitContext&) { | ||
| 131 | throw LogicError("Unreachable instruction"); | ||
| 132 | } | ||
| 133 | |||
| 118 | Id EmitBoundImageSampleImplicitLod(EmitContext&) { | 134 | Id 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 | ||
| 158 | Id EmitBoundImageFetch(EmitContext&) { | ||
| 159 | throw LogicError("Unreachable instruction"); | ||
| 160 | } | ||
| 161 | |||
| 142 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 162 | Id 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 | ||
| 180 | Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | 200 | Id 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 | ||
| 190 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 210 | Id 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 | ||
| 218 | Id 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 | ||
| 1494 | Value 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 | |||
| 1494 | U1 IREmitter::VoteAll(const U1& value) { | 1500 | U1 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, | |||
| 356 | OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) | 356 | OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) |
| 357 | OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) | 357 | OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 358 | OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 358 | OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 359 | OPCODE(BindlessImageFetch, F32x4, U32, Opaque, U32, U32, ) | ||
| 359 | 360 | ||
| 360 | OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 361 | OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 361 | OPCODE(BoundImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 362 | OPCODE(BoundImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| @@ -363,6 +364,7 @@ OPCODE(BoundImageSampleDrefImplicitLod, F32, U32, | |||
| 363 | OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) | 364 | OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) |
| 364 | OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) | 365 | OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 365 | OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 366 | OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 367 | OPCODE(BoundImageFetch, F32x4, U32, Opaque, U32, U32, ) | ||
| 366 | 368 | ||
| 367 | OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 369 | OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 368 | OPCODE(ImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 370 | OPCODE(ImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| @@ -370,6 +372,7 @@ OPCODE(ImageSampleDrefImplicitLod, F32, U32, | |||
| 370 | OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) | 372 | OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) |
| 371 | OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) | 373 | OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 372 | OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 374 | OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 375 | OPCODE(ImageFetch, F32x4, U32, Opaque, U32, U32, ) | ||
| 373 | 376 | ||
| 374 | // Warp operations | 377 | // Warp operations |
| 375 | OPCODE(VoteAll, U1, U1, ) | 378 | OPCODE(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()); |