diff options
| author | 2021-05-29 01:06:29 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:36 -0400 | |
| commit | 55e0211a5e520482246273f2cc64388c4b4eff1c (patch) | |
| tree | 1ae4461b0384924e90d2bdbaebcec1b57fdcabcd /src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |
| parent | glsl: Rework Shuffle emit instructions to align with SPIR-V (diff) | |
| download | yuzu-55e0211a5e520482246273f2cc64388c4b4eff1c.tar.gz yuzu-55e0211a5e520482246273f2cc64388c4b4eff1c.tar.xz yuzu-55e0211a5e520482246273f2cc64388c4b4eff1c.zip | |
glsl: Implement TEX ImageSample functions
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_glsl_image.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 1a34fe9b3..71eb3ac2b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
| 12 | namespace { | 12 | namespace { |
| 13 | std::string Texture(EmitContext& ctx, IR::TextureInstInfo info, | 13 | std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info, |
| 14 | [[maybe_unused]] const IR::Value& index) { | 14 | [[maybe_unused]] const IR::Value& index) { |
| 15 | if (info.type == TextureType::Buffer) { | 15 | if (info.type == TextureType::Buffer) { |
| 16 | throw NotImplementedException("TextureType::Buffer"); | 16 | throw NotImplementedException("TextureType::Buffer"); |
| @@ -18,6 +18,32 @@ std::string Texture(EmitContext& ctx, IR::TextureInstInfo info, | |||
| 18 | return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); | 18 | return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); |
| 19 | } | 19 | } |
| 20 | } | 20 | } |
| 21 | |||
| 22 | std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) { | ||
| 23 | switch (info.type) { | ||
| 24 | case TextureType::Color1D: | ||
| 25 | return fmt::format("int({})", value); | ||
| 26 | case TextureType::ColorArray1D: | ||
| 27 | case TextureType::Color2D: | ||
| 28 | return fmt::format("ivec2({})", value); | ||
| 29 | case TextureType::ColorArray2D: | ||
| 30 | case TextureType::Color3D: | ||
| 31 | case TextureType::ColorCube: | ||
| 32 | return fmt::format("ivec3({})", value); | ||
| 33 | case TextureType::ColorArrayCube: | ||
| 34 | return fmt::format("ivec4({})", value); | ||
| 35 | default: | ||
| 36 | throw NotImplementedException("Offset type {}", info.type.Value()); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | IR::Inst* PrepareSparse(IR::Inst& inst) { | ||
| 41 | const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; | ||
| 42 | if (sparse_inst) { | ||
| 43 | sparse_inst->Invalidate(); | ||
| 44 | } | ||
| 45 | return sparse_inst; | ||
| 46 | } | ||
| 21 | } // namespace | 47 | } // namespace |
| 22 | 48 | ||
| 23 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 49 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| @@ -26,18 +52,30 @@ void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | |||
| 26 | [[maybe_unused]] std::string_view bias_lc, | 52 | [[maybe_unused]] std::string_view bias_lc, |
| 27 | [[maybe_unused]] const IR::Value& offset) { | 53 | [[maybe_unused]] const IR::Value& offset) { |
| 28 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 54 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 29 | if (info.has_bias) { | ||
| 30 | throw NotImplementedException("Bias texture samples"); | ||
| 31 | } | ||
| 32 | if (info.has_lod_clamp) { | 55 | if (info.has_lod_clamp) { |
| 33 | throw NotImplementedException("Lod clamp samples"); | 56 | throw NotImplementedException("Lod clamp samples"); |
| 34 | } | 57 | } |
| 35 | const auto texture{Texture(ctx, info, index)}; | 58 | const auto texture{Texture(ctx, info, index)}; |
| 59 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | ||
| 60 | const auto texel{ctx.reg_alloc.Define(inst, Type::F32x4)}; | ||
| 61 | const auto sparse_inst{PrepareSparse(inst)}; | ||
| 62 | if (!sparse_inst) { | ||
| 63 | if (!offset.IsEmpty()) { | ||
| 64 | ctx.Add("{}=textureOffset({},{},{}{});", texel, texture, coords, | ||
| 65 | CastToIntVec(ctx.reg_alloc.Consume(offset), info), bias); | ||
| 66 | } else { | ||
| 67 | ctx.Add("{}=texture({},{}{});", texel, texture, coords, bias); | ||
| 68 | } | ||
| 69 | return; | ||
| 70 | } | ||
| 71 | // TODO: Query sparseTexels extension support | ||
| 36 | if (!offset.IsEmpty()) { | 72 | if (!offset.IsEmpty()) { |
| 37 | ctx.AddF32x4("{}=textureOffset({},{},ivec2({}));", inst, texture, coords, | 73 | ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureOffsetARB({},{},{},{}{}));", |
| 38 | ctx.reg_alloc.Consume(offset)); | 74 | *sparse_inst, texture, coords, CastToIntVec(ctx.reg_alloc.Consume(offset), info), |
| 75 | texel, bias); | ||
| 39 | } else { | 76 | } else { |
| 40 | ctx.AddF32x4("{}=texture({},{});", inst, texture, coords); | 77 | ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureARB({},{},{}{}));", *sparse_inst, |
| 78 | texture, coords, texel, bias); | ||
| 41 | } | 79 | } |
| 42 | } | 80 | } |
| 43 | 81 | ||
| @@ -54,11 +92,24 @@ void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | |||
| 54 | throw NotImplementedException("Lod clamp samples"); | 92 | throw NotImplementedException("Lod clamp samples"); |
| 55 | } | 93 | } |
| 56 | const auto texture{Texture(ctx, info, index)}; | 94 | const auto texture{Texture(ctx, info, index)}; |
| 95 | const auto texel{ctx.reg_alloc.Define(inst, Type::F32x4)}; | ||
| 96 | const auto sparse_inst{PrepareSparse(inst)}; | ||
| 97 | if (!sparse_inst) { | ||
| 98 | if (!offset.IsEmpty()) { | ||
| 99 | ctx.Add("{}=textureLodOffset({},{},{},{});", texel, texture, coords, lod_lc, | ||
| 100 | CastToIntVec(ctx.reg_alloc.Consume(offset), info)); | ||
| 101 | } else { | ||
| 102 | ctx.Add("{}=textureLod({},{},{});", texel, texture, coords, lod_lc); | ||
| 103 | } | ||
| 104 | return; | ||
| 105 | } | ||
| 57 | if (!offset.IsEmpty()) { | 106 | if (!offset.IsEmpty()) { |
| 58 | ctx.AddF32x4("{}=textureLodOffset({},{},{},ivec2({}));", inst, texture, coords, lod_lc, | 107 | ctx.AddU1("{}=sparseTexelsResidentARB(sparseTexelFetchOffsetARB({},{},int({}),{},{}));", |
| 59 | ctx.reg_alloc.Consume(offset)); | 108 | *sparse_inst, texture, CastToIntVec(coords, info), lod_lc, |
| 109 | CastToIntVec(ctx.reg_alloc.Consume(offset), info), texel); | ||
| 60 | } else { | 110 | } else { |
| 61 | ctx.AddF32x4("{}=textureLod({},{},{});", inst, texture, coords, lod_lc); | 111 | ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureLodARB({},{},{},{}));", *sparse_inst, |
| 112 | texture, coords, lod_lc, texel); | ||
| 62 | } | 113 | } |
| 63 | } | 114 | } |
| 64 | 115 | ||