mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	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{};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -226,6 +226,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
 | 
			
		||||
          .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
 | 
			
		||||
          .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
 | 
			
		||||
          .support_gl_vertex_viewport_layer = device.HasVertexViewportLayer(),
 | 
			
		||||
          .support_gl_texture_shadow_lod = device.HasTextureShadowLod(),
 | 
			
		||||
 | 
			
		||||
          .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user