shader: Add IR opcode for ImageFetch
This commit is contained in:
		| @@ -343,12 +343,14 @@ Id EmitBindlessImageSampleDrefImplicitLod(EmitContext&); | ||||
| Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&); | ||||
| Id EmitBindlessImageGather(EmitContext&); | ||||
| Id EmitBindlessImageGatherDref(EmitContext&); | ||||
| Id EmitBindlessImageFetch(EmitContext&); | ||||
| Id EmitBoundImageSampleImplicitLod(EmitContext&); | ||||
| Id EmitBoundImageSampleExplicitLod(EmitContext&); | ||||
| Id EmitBoundImageSampleDrefImplicitLod(EmitContext&); | ||||
| Id EmitBoundImageSampleDrefExplicitLod(EmitContext&); | ||||
| Id EmitBoundImageGather(EmitContext&); | ||||
| Id EmitBoundImageGatherDref(EmitContext&); | ||||
| Id EmitBoundImageFetch(EmitContext&); | ||||
| Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | ||||
|                               Id bias_lc, Id offset); | ||||
| 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 | ||||
|                    Id offset2); | ||||
| Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | ||||
|                        Id offset, Id offset2, Id dref); | ||||
| Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | ||||
|                   Id lod, Id ms); | ||||
| Id EmitVoteAll(EmitContext& ctx, Id pred); | ||||
| Id EmitVoteAny(EmitContext& ctx, Id pred); | ||||
| Id EmitVoteEqual(EmitContext& ctx, Id pred); | ||||
|   | ||||
| @@ -170,7 +170,7 @@ Id EmitCompositeConstructArrayU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id | ||||
|         return ctx.ConstantComposite(ctx.array_U32x2, e1, e2, e3, e4); | ||||
|     } | ||||
|     if (ctx.profile.support_variadic_ptp) { | ||||
|         return OpCompositeConstruct(ctx.array_U32x2, e1, e2, e3, e4); | ||||
|         return ctx.OpCompositeConstruct(ctx.array_U32x2, e1, e2, e3, e4); | ||||
|     } | ||||
|     return {}; | ||||
| } | ||||
|   | ||||
| @@ -39,6 +39,18 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     explicit ImageOperands([[maybe_unused]] EmitContext& ctx, Id offset, Id lod, Id ms) { | ||||
|         if (Sirit::ValidId(lod)) { | ||||
|             Add(spv::ImageOperandsMask::Lod, lod); | ||||
|         } | ||||
|         if (Sirit::ValidId(offset)) { | ||||
|             Add(spv::ImageOperandsMask::Offset, offset); | ||||
|         } | ||||
|         if (Sirit::ValidId(ms)) { | ||||
|             Add(spv::ImageOperandsMask::Sample, ms); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void Add(spv::ImageOperandsMask new_mask, Id value) { | ||||
|         mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) | | ||||
|                                                    static_cast<unsigned>(new_mask)); | ||||
| @@ -115,6 +127,10 @@ Id EmitBindlessImageGatherDref(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitBindlessImageFetch(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitBoundImageSampleImplicitLod(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
| @@ -139,6 +155,10 @@ Id EmitBoundImageGatherDref(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitBoundImageFetch(EmitContext&) { | ||||
|     throw LogicError("Unreachable instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | ||||
|                               Id bias_lc, Id offset) { | ||||
|     const auto info{inst->Flags<IR::TextureInstInfo>()}; | ||||
| @@ -178,7 +198,7 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va | ||||
| } | ||||
|  | ||||
| Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | ||||
|                    [[maybe_unused]] Id offset2) { | ||||
|                    Id offset2) { | ||||
|     const auto info{inst->Flags<IR::TextureInstInfo>()}; | ||||
|     const ImageOperands operands(ctx, offset, offset2); | ||||
|     return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, | ||||
| @@ -188,11 +208,19 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id | ||||
| } | ||||
|  | ||||
| Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | ||||
|                        Id offset, [[maybe_unused]] Id offset2, Id dref) { | ||||
|                        Id offset, Id offset2, Id dref) { | ||||
|     const auto info{inst->Flags<IR::TextureInstInfo>()}; | ||||
|     const ImageOperands operands(ctx, offset, offset2); | ||||
|     return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, | ||||
|                 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); | ||||
| } | ||||
|  | ||||
| Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | ||||
|                   Id lod, Id ms) { | ||||
|     const auto info{inst->Flags<IR::TextureInstInfo>()}; | ||||
|     const ImageOperands operands(ctx, offset, lod, ms); | ||||
|     return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], | ||||
|                 Texture(ctx, index), coords, operands.Mask(), operands.Span()); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -1491,6 +1491,12 @@ Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const | ||||
|     return Inst(op, Flags{info}, handle, coords, offset, offset2, dref); | ||||
| } | ||||
|  | ||||
| Value IREmitter::ImageFetch(const Value& handle, const Value& coords, const Value& offset, | ||||
|                             const U32& lod, const U32& multisampling, TextureInstInfo info) { | ||||
|     const Opcode op{handle.IsImmediate() ? Opcode::BoundImageFetch : Opcode::BindlessImageFetch}; | ||||
|     return Inst(op, Flags{info}, handle, coords, offset, lod, multisampling); | ||||
| } | ||||
|  | ||||
| U1 IREmitter::VoteAll(const U1& value) { | ||||
|     return Inst<U1>(Opcode::VoteAll, value); | ||||
| } | ||||
|   | ||||
| @@ -243,8 +243,12 @@ public: | ||||
|     [[nodiscard]] Value ImageGather(const Value& handle, const Value& coords, const Value& offset, | ||||
|                                     const Value& offset2, TextureInstInfo info); | ||||
|  | ||||
|     [[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords, const Value& offset, | ||||
|                                       const Value& offset2, const F32& dref, TextureInstInfo info); | ||||
|     [[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords, | ||||
|                                         const Value& offset, const Value& offset2, const F32& dref, | ||||
|                                         TextureInstInfo info); | ||||
|  | ||||
|     [[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const Value& offset, | ||||
|                                    const U32& lod, const U32& multisampling, TextureInstInfo info); | ||||
|  | ||||
|     [[nodiscard]] U1 VoteAll(const U1& value); | ||||
|     [[nodiscard]] U1 VoteAny(const U1& value); | ||||
|   | ||||
| @@ -356,6 +356,7 @@ OPCODE(BindlessImageSampleDrefImplicitLod,                  F32,            U32, | ||||
| OPCODE(BindlessImageSampleDrefExplicitLod,                  F32,            U32,            Opaque,         F32,            Opaque,         Opaque,         ) | ||||
| OPCODE(BindlessImageGather,                                 F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| OPCODE(BindlessImageGatherDref,                             F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            ) | ||||
| OPCODE(BindlessImageFetch,                                  F32x4,          U32,            Opaque,         U32,            U32,                            ) | ||||
|  | ||||
| OPCODE(BoundImageSampleImplicitLod,                         F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| OPCODE(BoundImageSampleExplicitLod,                         F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| @@ -363,6 +364,7 @@ OPCODE(BoundImageSampleDrefImplicitLod,                     F32,            U32, | ||||
| OPCODE(BoundImageSampleDrefExplicitLod,                     F32,            U32,            Opaque,         F32,            Opaque,         Opaque,         ) | ||||
| OPCODE(BoundImageGather,                                    F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| OPCODE(BoundImageGatherDref,                                F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            ) | ||||
| OPCODE(BoundImageFetch,                                     F32x4,          U32,            Opaque,         U32,            U32,                            ) | ||||
|  | ||||
| OPCODE(ImageSampleImplicitLod,                              F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| OPCODE(ImageSampleExplicitLod,                              F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| @@ -370,6 +372,7 @@ OPCODE(ImageSampleDrefImplicitLod,                          F32,            U32, | ||||
| OPCODE(ImageSampleDrefExplicitLod,                          F32,            U32,            Opaque,         F32,            Opaque,         Opaque,         ) | ||||
| OPCODE(ImageGather,                                         F32x4,          U32,            Opaque,         Opaque,         Opaque,                         ) | ||||
| OPCODE(ImageGatherDref,                                     F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            ) | ||||
| OPCODE(ImageFetch,                                          F32x4,          U32,            Opaque,         U32,            U32,                            ) | ||||
|  | ||||
| // Warp operations | ||||
| OPCODE(VoteAll,                                             U1,             U1,                                                                             ) | ||||
|   | ||||
| @@ -51,6 +51,9 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) { | ||||
|     case IR::Opcode::BindlessImageGatherDref: | ||||
|     case IR::Opcode::BoundImageGatherDref: | ||||
|         return IR::Opcode::ImageGatherDref; | ||||
|     case IR::Opcode::BindlessImageFetch: | ||||
|     case IR::Opcode::BoundImageFetch: | ||||
|         return IR::Opcode::ImageFetch; | ||||
|     default: | ||||
|         return IR::Opcode::Void; | ||||
|     } | ||||
| @@ -64,6 +67,7 @@ bool IsBindless(const IR::Inst& inst) { | ||||
|     case IR::Opcode::BindlessImageSampleDrefExplicitLod: | ||||
|     case IR::Opcode::BindlessImageGather: | ||||
|     case IR::Opcode::BindlessImageGatherDref: | ||||
|     case IR::Opcode::BindlessImageFetch: | ||||
|         return true; | ||||
|     case IR::Opcode::BoundImageSampleImplicitLod: | ||||
|     case IR::Opcode::BoundImageSampleExplicitLod: | ||||
| @@ -71,6 +75,7 @@ bool IsBindless(const IR::Inst& inst) { | ||||
|     case IR::Opcode::BoundImageSampleDrefExplicitLod: | ||||
|     case IR::Opcode::BoundImageGather: | ||||
|     case IR::Opcode::BoundImageGatherDref: | ||||
|     case IR::Opcode::BoundImageFetch: | ||||
|         return false; | ||||
|     default: | ||||
|         throw InvalidArgument("Invalid opcode {}", inst.Opcode()); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user