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&) { | void EmitContext::SetupExtensions(std::string&) { | ||||||
|     // TODO: track this usage |     // TODO: track this usage | ||||||
|     header += "#extension GL_ARB_sparse_texture2 : enable\n" |     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"; |               "#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) { |     if (info.uses_int64) { | ||||||
|         header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |         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/backend/glsl/emit_glsl_instructions.h" | ||||||
| #include "shader_recompiler/frontend/ir/modifiers.h" | #include "shader_recompiler/frontend/ir/modifiers.h" | ||||||
| #include "shader_recompiler/frontend/ir/value.h" | #include "shader_recompiler/frontend/ir/value.h" | ||||||
|  | #include "shader_recompiler/profile.h" | ||||||
|  |  | ||||||
| namespace Shader::Backend::GLSL { | namespace Shader::Backend::GLSL { | ||||||
| namespace { | 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) { |     switch (type) { | ||||||
|     case TextureType::ColorArray2D: |     case TextureType::ColorArray2D: | ||||||
|     case TextureType::ColorCube: |     case TextureType::ColorCube: | ||||||
|     case TextureType::ColorArrayCube: |     case TextureType::ColorArrayCube: | ||||||
|         return "vec4"; |         return true; | ||||||
|     default: |     default: | ||||||
|         return "vec3"; |         return false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -221,7 +222,22 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | |||||||
|     } |     } | ||||||
|     const auto texture{Texture(ctx, info, index)}; |     const auto texture{Texture(ctx, info, index)}; | ||||||
|     const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; |     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()) { |     if (!offset.IsEmpty()) { | ||||||
|         const auto offset_str{GetOffsetVec(ctx, offset)}; |         const auto offset_str{GetOffsetVec(ctx, offset)}; | ||||||
|         if (ctx.stage == Stage::Fragment) { |         if (ctx.stage == Stage::Fragment) { | ||||||
| @@ -263,15 +279,29 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | |||||||
|         throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); |         throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); | ||||||
|     } |     } | ||||||
|     const auto texture{Texture(ctx, info, index)}; |     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()) { |     if (!offset.IsEmpty()) { | ||||||
|         const auto offset_str{GetOffsetVec(ctx, offset)}; |         const auto offset_str{GetOffsetVec(ctx, offset)}; | ||||||
|         if (info.type == TextureType::ColorArrayCube) { |         if (info.type == TextureType::ColorArrayCube) { | ||||||
|             ctx.AddF32("{}=textureLodOffset({},{},{},{},{});", inst, texture, coords, dref, lod_lc, |             ctx.AddF32("{}=textureLodOffset({},{},{},{},{});", inst, texture, coords, dref, lod_lc, | ||||||
|                        offset_str); |                        offset_str); | ||||||
|         } else { |         } else { | ||||||
|             ctx.AddF32("{}=textureLodOffset({},vec3({},{}),{},{});", inst, texture, coords, dref, |             ctx.AddF32("{}=textureLodOffset({},{}({},{}),{},{});", inst, texture, cast, coords, | ||||||
|                        lod_lc, offset_str); |                        dref, lod_lc, offset_str); | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|         if (info.type == TextureType::ColorArrayCube) { |         if (info.type == TextureType::ColorArrayCube) { | ||||||
|   | |||||||
| @@ -86,6 +86,7 @@ struct Profile { | |||||||
|     bool support_gl_nv_gpu_shader_5{}; |     bool support_gl_nv_gpu_shader_5{}; | ||||||
|     bool support_gl_amd_gpu_shader_half_float{}; |     bool support_gl_amd_gpu_shader_half_float{}; | ||||||
|     bool support_gl_vertex_viewport_layer{}; |     bool support_gl_vertex_viewport_layer{}; | ||||||
|  |     bool support_gl_texture_shadow_lod{}; | ||||||
|  |  | ||||||
|     bool warp_size_potentially_larger_than_guest{}; |     bool warp_size_potentially_larger_than_guest{}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -226,6 +226,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | |||||||
|           .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(), |           .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(), | ||||||
|           .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(), |           .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(), | ||||||
|           .support_gl_vertex_viewport_layer = device.HasVertexViewportLayer(), |           .support_gl_vertex_viewport_layer = device.HasVertexViewportLayer(), | ||||||
|  |           .support_gl_texture_shadow_lod = device.HasTextureShadowLod(), | ||||||
|  |  | ||||||
|           .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(), |           .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(), | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user