glsl: Use textureGrad fallback when EXT_texture_shadow_lod is unsupported
This commit is contained in:
		| @@ -282,8 +282,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | ||||
| void EmitContext::SetupExtensions(std::string&) { | ||||
|     // TODO: track this usage | ||||
|     header += "#extension GL_ARB_sparse_texture2 : enable\n" | ||||
|               "#extension GL_EXT_texture_shadow_lod : enable\n" | ||||
|               "#extension GL_EXT_shader_image_load_formatted : enable\n"; | ||||
|     if (profile.support_gl_texture_shadow_lod) { | ||||
|         header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | ||||
|     } | ||||
|     if (info.uses_int64) { | ||||
|         header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | ||||
|     } | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||||
| #include "shader_recompiler/frontend/ir/modifiers.h" | ||||
| #include "shader_recompiler/frontend/ir/value.h" | ||||
| #include "shader_recompiler/profile.h" | ||||
|  | ||||
| namespace Shader::Backend::GLSL { | ||||
| namespace { | ||||
| @@ -67,14 +68,14 @@ std::string TexelFetchCastToInt(std::string_view value, const IR::TextureInstInf | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::string ShadowSamplerVecCast(TextureType type) { | ||||
| bool NeedsShadowLodExt(TextureType type) { | ||||
|     switch (type) { | ||||
|     case TextureType::ColorArray2D: | ||||
|     case TextureType::ColorCube: | ||||
|     case TextureType::ColorArrayCube: | ||||
|         return "vec4"; | ||||
|         return true; | ||||
|     default: | ||||
|         return "vec3"; | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -221,7 +222,22 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | ||||
|     const auto cast{ShadowSamplerVecCast(info.type)}; | ||||
|     const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; | ||||
|     const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; | ||||
|     const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && | ||||
|                         ctx.stage != Stage::Fragment && needs_shadow_ext}; | ||||
|     if (use_grad) { | ||||
|         // LOG_WARNING(..., "Device lacks GL_EXT_texture_shadow_lod. Using textureGrad fallback"); | ||||
|         if (info.type == TextureType::ColorArrayCube) { | ||||
|             // LOG_WARNING(..., "textureGrad does not support ColorArrayCube. Stubbing"); | ||||
|             ctx.AddF32("{}=0.0f;", inst); | ||||
|             return; | ||||
|         } | ||||
|         const auto d_cast{info.type == TextureType::ColorArray2D ? "vec2" : "vec3"}; | ||||
|         ctx.AddF32("{}=textureGrad({},{}({},{}),{}(0),{}(0));", inst, texture, cast, coords, dref, | ||||
|                    d_cast, d_cast); | ||||
|         return; | ||||
|     } | ||||
|     if (!offset.IsEmpty()) { | ||||
|         const auto offset_str{GetOffsetVec(ctx, offset)}; | ||||
|         if (ctx.stage == Stage::Fragment) { | ||||
| @@ -263,15 +279,29 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | ||||
|         throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto cast{ShadowSamplerVecCast(info.type)}; | ||||
|     const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; | ||||
|     const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext}; | ||||
|     const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; | ||||
|     if (use_grad) { | ||||
|         // LOG_WARNING(..., "Device lacks GL_EXT_texture_shadow_lod. Using textureGrad fallback"); | ||||
|         if (info.type == TextureType::ColorArrayCube) { | ||||
|             // LOG_WARNING(..., "textureGrad does not support ColorArrayCube. Stubbing"); | ||||
|             ctx.AddF32("{}=0.0f;", inst); | ||||
|             return; | ||||
|         } | ||||
|         const auto d_cast{info.type == TextureType::ColorArray2D ? "vec2" : "vec3"}; | ||||
|         ctx.AddF32("{}=textureGrad({},{}({},{}),{}(0),{}(0));", inst, texture, cast, coords, dref, | ||||
|                    d_cast, d_cast); | ||||
|         return; | ||||
|     } | ||||
|     if (!offset.IsEmpty()) { | ||||
|         const auto offset_str{GetOffsetVec(ctx, offset)}; | ||||
|         if (info.type == TextureType::ColorArrayCube) { | ||||
|             ctx.AddF32("{}=textureLodOffset({},{},{},{},{});", inst, texture, coords, dref, lod_lc, | ||||
|                        offset_str); | ||||
|         } else { | ||||
|             ctx.AddF32("{}=textureLodOffset({},vec3({},{}),{},{});", inst, texture, coords, dref, | ||||
|                        lod_lc, offset_str); | ||||
|             ctx.AddF32("{}=textureLodOffset({},{}({},{}),{},{});", inst, texture, cast, coords, | ||||
|                        dref, lod_lc, offset_str); | ||||
|         } | ||||
|     } else { | ||||
|         if (info.type == TextureType::ColorArrayCube) { | ||||
|   | ||||
| @@ -86,6 +86,7 @@ struct Profile { | ||||
|     bool support_gl_nv_gpu_shader_5{}; | ||||
|     bool support_gl_amd_gpu_shader_half_float{}; | ||||
|     bool support_gl_vertex_viewport_layer{}; | ||||
|     bool support_gl_texture_shadow_lod{}; | ||||
|  | ||||
|     bool warp_size_potentially_larger_than_guest{}; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user