mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-27 09:12:46 +01:00
glasm: Implement ImageRead
This commit is contained in:
parent
3d0ffc6ad0
commit
dadd192b30
4 changed files with 56 additions and 4 deletions
|
@ -82,6 +82,16 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
|
||||||
Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index);
|
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());
|
texture_buffer_bindings.reserve(program.info.texture_buffer_descriptors.size());
|
||||||
for (const auto& desc : program.info.texture_buffer_descriptors) {
|
for (const auto& desc : program.info.texture_buffer_descriptors) {
|
||||||
texture_buffer_bindings.push_back(bindings.texture);
|
texture_buffer_bindings.push_back(bindings.texture);
|
||||||
|
|
|
@ -60,7 +60,9 @@ public:
|
||||||
const Profile& profile;
|
const Profile& profile;
|
||||||
|
|
||||||
std::vector<u32> texture_buffer_bindings;
|
std::vector<u32> texture_buffer_bindings;
|
||||||
|
std::vector<u32> image_buffer_bindings;
|
||||||
std::vector<u32> texture_bindings;
|
std::vector<u32> texture_bindings;
|
||||||
|
std::vector<u32> image_bindings;
|
||||||
|
|
||||||
Stage stage{};
|
Stage stage{};
|
||||||
std::string_view stage_name = "invalid";
|
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_shader_storage_buffer;"
|
||||||
"OPTION NV_gpu_program_fp64;"
|
"OPTION NV_gpu_program_fp64;"
|
||||||
"OPTION NV_bindless_texture;"
|
"OPTION NV_bindless_texture;"
|
||||||
"OPTION ARB_derivative_control;";
|
"OPTION ARB_derivative_control;"
|
||||||
|
"OPTION EXT_shader_image_load_formatted;";
|
||||||
if (info.uses_int64_bit_atomics) {
|
if (info.uses_int64_bit_atomics) {
|
||||||
header += "OPTION NV_shader_atomic_int64;";
|
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) {
|
std::string_view TextureType(IR::TextureInstInfo info) {
|
||||||
if (info.is_depth) {
|
if (info.is_depth) {
|
||||||
switch (info.type) {
|
switch (info.type) {
|
||||||
|
@ -173,6 +183,28 @@ void StoreSparse(EmitContext& ctx, IR::Inst* sparse_inst) {
|
||||||
sparse_ret, sparse_ret);
|
sparse_ret, sparse_ret);
|
||||||
sparse_inst->Invalidate();
|
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
|
} // Anonymous namespace
|
||||||
|
|
||||||
void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
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);
|
StoreSparse(ctx, sparse_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
|
void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord) {
|
||||||
[[maybe_unused]] const IR::Value& index, [[maybe_unused]] Register coord) {
|
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
||||||
throw NotImplementedException("GLASM instruction");
|
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,
|
void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
|
||||||
|
|
Loading…
Reference in a new issue