diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_context.cpp | 9 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp | 2 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | 71 |
3 files changed, 71 insertions, 11 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index db62ba73b..eb1d8266f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -23,6 +23,10 @@ std::string_view InterpDecorator(Interpolation interp) { | |||
| 23 | 23 | ||
| 24 | std::string_view SamplerType(TextureType type) { | 24 | std::string_view SamplerType(TextureType type) { |
| 25 | switch (type) { | 25 | switch (type) { |
| 26 | case TextureType::Color1D: | ||
| 27 | return "sampler1D"; | ||
| 28 | case TextureType::ColorArray1D: | ||
| 29 | return "sampler1DArray"; | ||
| 26 | case TextureType::Color2D: | 30 | case TextureType::Color2D: |
| 27 | return "sampler2D"; | 31 | return "sampler2D"; |
| 28 | case TextureType::ColorArray2D: | 32 | case TextureType::ColorArray2D: |
| @@ -31,6 +35,10 @@ std::string_view SamplerType(TextureType type) { | |||
| 31 | return "sampler3D"; | 35 | return "sampler3D"; |
| 32 | case TextureType::ColorCube: | 36 | case TextureType::ColorCube: |
| 33 | return "samplerCube"; | 37 | return "samplerCube"; |
| 38 | case TextureType::ColorArrayCube: | ||
| 39 | return "samplerCubeArray"; | ||
| 40 | case TextureType::Buffer: | ||
| 41 | return "samplerBuffer"; | ||
| 34 | default: | 42 | default: |
| 35 | fmt::print("Texture type: {}", type); | 43 | fmt::print("Texture type: {}", type); |
| 36 | throw NotImplementedException("Texture type: {}", type); | 44 | throw NotImplementedException("Texture type: {}", type); |
| @@ -101,6 +109,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 101 | 109 | ||
| 102 | void EmitContext::SetupExtensions(std::string&) { | 110 | void EmitContext::SetupExtensions(std::string&) { |
| 103 | header += "#extension GL_ARB_separate_shader_objects : enable\n"; | 111 | header += "#extension GL_ARB_separate_shader_objects : enable\n"; |
| 112 | header += "#extension GL_ARB_sparse_texture2 : enable\n"; | ||
| 104 | // header += "#extension GL_ARB_texture_cube_map_array : enable\n"; | 113 | // header += "#extension GL_ARB_texture_cube_map_array : enable\n"; |
| 105 | if (info.uses_int64) { | 114 | if (info.uses_int64) { |
| 106 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | 115 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp index fa1b02af1..087eaea8f 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp | |||
| @@ -195,7 +195,7 @@ void EmitConvertF32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::In | |||
| 195 | 195 | ||
| 196 | void EmitConvertF32U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 196 | void EmitConvertF32U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 197 | [[maybe_unused]] std::string_view value) { | 197 | [[maybe_unused]] std::string_view value) { |
| 198 | ctx.AddF32("{}=float(uint({}));", inst, value); | 198 | ctx.AddF32("{}=float(uint({}&0xffff));", inst, value); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | void EmitConvertF32U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 201 | void EmitConvertF32U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
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 | ||