glasm: Implement ImageRead
This commit is contained in:
		| @@ -82,6 +82,16 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | ||||
|             Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index); | ||||
|         } | ||||
|     } | ||||
|     image_buffer_bindings.reserve(program.info.image_buffer_descriptors.size()); | ||||
|     for (const auto& desc : program.info.image_buffer_descriptors) { | ||||
|         image_buffer_bindings.push_back(bindings.image); | ||||
|         bindings.image += desc.count; | ||||
|     } | ||||
|     image_bindings.reserve(program.info.image_descriptors.size()); | ||||
|     for (const auto& desc : program.info.image_descriptors) { | ||||
|         image_bindings.push_back(bindings.image); | ||||
|         bindings.image += desc.count; | ||||
|     } | ||||
|     texture_buffer_bindings.reserve(program.info.texture_buffer_descriptors.size()); | ||||
|     for (const auto& desc : program.info.texture_buffer_descriptors) { | ||||
|         texture_buffer_bindings.push_back(bindings.texture); | ||||
|   | ||||
| @@ -60,7 +60,9 @@ public: | ||||
|     const Profile& profile; | ||||
|  | ||||
|     std::vector<u32> texture_buffer_bindings; | ||||
|     std::vector<u32> image_buffer_bindings; | ||||
|     std::vector<u32> texture_bindings; | ||||
|     std::vector<u32> image_bindings; | ||||
|  | ||||
|     Stage stage{}; | ||||
|     std::string_view stage_name = "invalid"; | ||||
|   | ||||
| @@ -270,7 +270,8 @@ void SetupOptions(const IR::Program& program, const Profile& profile, std::strin | ||||
|               "OPTION NV_shader_storage_buffer;" | ||||
|               "OPTION NV_gpu_program_fp64;" | ||||
|               "OPTION NV_bindless_texture;" | ||||
|               "OPTION ARB_derivative_control;"; | ||||
|               "OPTION ARB_derivative_control;" | ||||
|               "OPTION EXT_shader_image_load_formatted;"; | ||||
|     if (info.uses_int64_bit_atomics) { | ||||
|         header += "OPTION NV_shader_atomic_int64;"; | ||||
|     } | ||||
|   | ||||
| @@ -50,6 +50,16 @@ std::string Texture(EmitContext& ctx, IR::TextureInstInfo info, | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::string Image(EmitContext& ctx, IR::TextureInstInfo info, | ||||
|                   [[maybe_unused]] const IR::Value& index) { | ||||
|     // FIXME: indexed reads | ||||
|     if (info.type == TextureType::Buffer) { | ||||
|         return fmt::format("image[{}]", ctx.image_buffer_bindings.at(info.descriptor_index)); | ||||
|     } else { | ||||
|         return fmt::format("image[{}]", ctx.image_bindings.at(info.descriptor_index)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::string_view TextureType(IR::TextureInstInfo info) { | ||||
|     if (info.is_depth) { | ||||
|         switch (info.type) { | ||||
| @@ -173,6 +183,28 @@ void StoreSparse(EmitContext& ctx, IR::Inst* sparse_inst) { | ||||
|             sparse_ret, sparse_ret); | ||||
|     sparse_inst->Invalidate(); | ||||
| } | ||||
|  | ||||
| std::string_view FormatStorage(ImageFormat format) { | ||||
|     switch (format) { | ||||
|     case ImageFormat::Typeless: | ||||
|         return "U"; | ||||
|     case ImageFormat::R8_UINT: | ||||
|         return "U8"; | ||||
|     case ImageFormat::R8_SINT: | ||||
|         return "S8"; | ||||
|     case ImageFormat::R16_UINT: | ||||
|         return "U16"; | ||||
|     case ImageFormat::R16_SINT: | ||||
|         return "S16"; | ||||
|     case ImageFormat::R32_UINT: | ||||
|         return "U32"; | ||||
|     case ImageFormat::R32G32_UINT: | ||||
|         return "U32X2"; | ||||
|     case ImageFormat::R32G32B32A32_UINT: | ||||
|         return "U32X4"; | ||||
|     } | ||||
|     throw InvalidArgument("Invalid image format {}", format); | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
| void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
| @@ -528,9 +560,16 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|     StoreSparse(ctx, sparse_inst); | ||||
| } | ||||
|  | ||||
| void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||
|                    [[maybe_unused]] const IR::Value& index, [[maybe_unused]] Register coord) { | ||||
|     throw NotImplementedException("GLASM instruction"); | ||||
| void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord) { | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; | ||||
|     const std::string_view format{FormatStorage(info.image_format)}; | ||||
|     const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; | ||||
|     const std::string_view type{TextureType(info)}; | ||||
|     const std::string image{Image(ctx, info, index)}; | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     ctx.Add("LOADIM.{}{} {},{},{},{};", format, sparse_mod, ret, coord, image, type); | ||||
|     StoreSparse(ctx, sparse_inst); | ||||
| } | ||||
|  | ||||
| void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user