summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.cpp10
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.h2
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp3
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_image.cpp45
4 files changed, 56 insertions, 4 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/emit_context.cpp
index 463930a18..8f418936e 100644
--- a/src/shader_recompiler/backend/glasm/emit_context.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_context.cpp
@@ -82,6 +82,16 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
82 Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index); 82 Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index);
83 } 83 }
84 } 84 }
85 image_buffer_bindings.reserve(program.info.image_buffer_descriptors.size());
86 for (const auto& desc : program.info.image_buffer_descriptors) {
87 image_buffer_bindings.push_back(bindings.image);
88 bindings.image += desc.count;
89 }
90 image_bindings.reserve(program.info.image_descriptors.size());
91 for (const auto& desc : program.info.image_descriptors) {
92 image_bindings.push_back(bindings.image);
93 bindings.image += desc.count;
94 }
85 texture_buffer_bindings.reserve(program.info.texture_buffer_descriptors.size()); 95 texture_buffer_bindings.reserve(program.info.texture_buffer_descriptors.size());
86 for (const auto& desc : program.info.texture_buffer_descriptors) { 96 for (const auto& desc : program.info.texture_buffer_descriptors) {
87 texture_buffer_bindings.push_back(bindings.texture); 97 texture_buffer_bindings.push_back(bindings.texture);
diff --git a/src/shader_recompiler/backend/glasm/emit_context.h b/src/shader_recompiler/backend/glasm/emit_context.h
index dd1f9ac9f..d5bab48ea 100644
--- a/src/shader_recompiler/backend/glasm/emit_context.h
+++ b/src/shader_recompiler/backend/glasm/emit_context.h
@@ -60,7 +60,9 @@ public:
60 const Profile& profile; 60 const Profile& profile;
61 61
62 std::vector<u32> texture_buffer_bindings; 62 std::vector<u32> texture_buffer_bindings;
63 std::vector<u32> image_buffer_bindings;
63 std::vector<u32> texture_bindings; 64 std::vector<u32> texture_bindings;
65 std::vector<u32> image_bindings;
64 66
65 Stage stage{}; 67 Stage stage{};
66 std::string_view stage_name = "invalid"; 68 std::string_view stage_name = "invalid";
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 9dc0cacbe..3910d00ee 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -270,7 +270,8 @@ void SetupOptions(const IR::Program& program, const Profile& profile, std::strin
270 "OPTION NV_shader_storage_buffer;" 270 "OPTION NV_shader_storage_buffer;"
271 "OPTION NV_gpu_program_fp64;" 271 "OPTION NV_gpu_program_fp64;"
272 "OPTION NV_bindless_texture;" 272 "OPTION NV_bindless_texture;"
273 "OPTION ARB_derivative_control;"; 273 "OPTION ARB_derivative_control;"
274 "OPTION EXT_shader_image_load_formatted;";
274 if (info.uses_int64_bit_atomics) { 275 if (info.uses_int64_bit_atomics) {
275 header += "OPTION NV_shader_atomic_int64;"; 276 header += "OPTION NV_shader_atomic_int64;";
276 } 277 }
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
index ab5a694fd..beee9cf06 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
@@ -50,6 +50,16 @@ std::string Texture(EmitContext& ctx, IR::TextureInstInfo info,
50 } 50 }
51} 51}
52 52
53std::string Image(EmitContext& ctx, IR::TextureInstInfo info,
54 [[maybe_unused]] const IR::Value& index) {
55 // FIXME: indexed reads
56 if (info.type == TextureType::Buffer) {
57 return fmt::format("image[{}]", ctx.image_buffer_bindings.at(info.descriptor_index));
58 } else {
59 return fmt::format("image[{}]", ctx.image_bindings.at(info.descriptor_index));
60 }
61}
62
53std::string_view TextureType(IR::TextureInstInfo info) { 63std::string_view TextureType(IR::TextureInstInfo info) {
54 if (info.is_depth) { 64 if (info.is_depth) {
55 switch (info.type) { 65 switch (info.type) {
@@ -173,6 +183,28 @@ void StoreSparse(EmitContext& ctx, IR::Inst* sparse_inst) {
173 sparse_ret, sparse_ret); 183 sparse_ret, sparse_ret);
174 sparse_inst->Invalidate(); 184 sparse_inst->Invalidate();
175} 185}
186
187std::string_view FormatStorage(ImageFormat format) {
188 switch (format) {
189 case ImageFormat::Typeless:
190 return "U";
191 case ImageFormat::R8_UINT:
192 return "U8";
193 case ImageFormat::R8_SINT:
194 return "S8";
195 case ImageFormat::R16_UINT:
196 return "U16";
197 case ImageFormat::R16_SINT:
198 return "S16";
199 case ImageFormat::R32_UINT:
200 return "U32";
201 case ImageFormat::R32G32_UINT:
202 return "U32X2";
203 case ImageFormat::R32G32B32A32_UINT:
204 return "U32X4";
205 }
206 throw InvalidArgument("Invalid image format {}", format);
207}
176} // Anonymous namespace 208} // Anonymous namespace
177 209
178void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 210void 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,
528 StoreSparse(ctx, sparse_inst); 560 StoreSparse(ctx, sparse_inst);
529} 561}
530 562
531void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 563void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord) {
532 [[maybe_unused]] const IR::Value& index, [[maybe_unused]] Register coord) { 564 const auto info{inst.Flags<IR::TextureInstInfo>()};
533 throw NotImplementedException("GLASM instruction"); 565 const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
566 const std::string_view format{FormatStorage(info.image_format)};
567 const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
568 const std::string_view type{TextureType(info)};
569 const std::string image{Image(ctx, info, index)};
570 const Register ret{ctx.reg_alloc.Define(inst)};
571 ctx.Add("LOADIM.{}{} {},{},{},{};", format, sparse_mod, ret, coord, image, type);
572 StoreSparse(ctx, sparse_inst);
534} 573}
535 574
536void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 575void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,