Merge pull request #4129 from Morph1984/texture-shadow-lod-workaround
gl_shader_decompiler: Workaround textureLod when GL_EXT_texture_shadow_lod is not available
This commit is contained in:
		
						commit
						b66ccaa376
					
				@ -216,6 +216,7 @@ Device::Device()
 | 
			
		||||
    has_shader_ballot = GLAD_GL_ARB_shader_ballot;
 | 
			
		||||
    has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array;
 | 
			
		||||
    has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted");
 | 
			
		||||
    has_texture_shadow_lod = HasExtension(extensions, "GL_EXT_texture_shadow_lod");
 | 
			
		||||
    has_astc = IsASTCSupported();
 | 
			
		||||
    has_variable_aoffi = TestVariableAoffi();
 | 
			
		||||
    has_component_indexing_bug = is_amd;
 | 
			
		||||
@ -245,6 +246,7 @@ Device::Device(std::nullptr_t) {
 | 
			
		||||
    has_shader_ballot = true;
 | 
			
		||||
    has_vertex_viewport_layer = true;
 | 
			
		||||
    has_image_load_formatted = true;
 | 
			
		||||
    has_texture_shadow_lod = true;
 | 
			
		||||
    has_variable_aoffi = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,10 @@ public:
 | 
			
		||||
        return has_image_load_formatted;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool HasTextureShadowLod() const {
 | 
			
		||||
        return has_texture_shadow_lod;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool HasASTC() const {
 | 
			
		||||
        return has_astc;
 | 
			
		||||
    }
 | 
			
		||||
@ -110,6 +114,7 @@ private:
 | 
			
		||||
    bool has_shader_ballot{};
 | 
			
		||||
    bool has_vertex_viewport_layer{};
 | 
			
		||||
    bool has_image_load_formatted{};
 | 
			
		||||
    bool has_texture_shadow_lod{};
 | 
			
		||||
    bool has_astc{};
 | 
			
		||||
    bool has_variable_aoffi{};
 | 
			
		||||
    bool has_component_indexing_bug{};
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ using Tegra::Shader::IpaMode;
 | 
			
		||||
using Tegra::Shader::IpaSampleMode;
 | 
			
		||||
using Tegra::Shader::PixelImap;
 | 
			
		||||
using Tegra::Shader::Register;
 | 
			
		||||
using Tegra::Shader::TextureType;
 | 
			
		||||
using VideoCommon::Shader::BuildTransformFeedback;
 | 
			
		||||
using VideoCommon::Shader::Registry;
 | 
			
		||||
 | 
			
		||||
@ -526,6 +527,9 @@ private:
 | 
			
		||||
        if (device.HasImageLoadFormatted()) {
 | 
			
		||||
            code.AddLine("#extension GL_EXT_shader_image_load_formatted : require");
 | 
			
		||||
        }
 | 
			
		||||
        if (device.HasTextureShadowLod()) {
 | 
			
		||||
            code.AddLine("#extension GL_EXT_texture_shadow_lod : require");
 | 
			
		||||
        }
 | 
			
		||||
        if (device.HasWarpIntrinsics()) {
 | 
			
		||||
            code.AddLine("#extension GL_NV_gpu_shader5 : require");
 | 
			
		||||
            code.AddLine("#extension GL_NV_shader_thread_group : require");
 | 
			
		||||
@ -909,13 +913,13 @@ private:
 | 
			
		||||
                    return "samplerBuffer";
 | 
			
		||||
                }
 | 
			
		||||
                switch (sampler.type) {
 | 
			
		||||
                case Tegra::Shader::TextureType::Texture1D:
 | 
			
		||||
                case TextureType::Texture1D:
 | 
			
		||||
                    return "sampler1D";
 | 
			
		||||
                case Tegra::Shader::TextureType::Texture2D:
 | 
			
		||||
                case TextureType::Texture2D:
 | 
			
		||||
                    return "sampler2D";
 | 
			
		||||
                case Tegra::Shader::TextureType::Texture3D:
 | 
			
		||||
                case TextureType::Texture3D:
 | 
			
		||||
                    return "sampler3D";
 | 
			
		||||
                case Tegra::Shader::TextureType::TextureCube:
 | 
			
		||||
                case TextureType::TextureCube:
 | 
			
		||||
                    return "samplerCube";
 | 
			
		||||
                default:
 | 
			
		||||
                    UNREACHABLE();
 | 
			
		||||
@ -1380,8 +1384,19 @@ private:
 | 
			
		||||
        const std::size_t count = operation.GetOperandsCount();
 | 
			
		||||
        const bool has_array = meta->sampler.is_array;
 | 
			
		||||
        const bool has_shadow = meta->sampler.is_shadow;
 | 
			
		||||
        const bool workaround_lod_array_shadow_as_grad =
 | 
			
		||||
            !device.HasTextureShadowLod() && function_suffix == "Lod" && meta->sampler.is_shadow &&
 | 
			
		||||
            ((meta->sampler.type == TextureType::Texture2D && meta->sampler.is_array) ||
 | 
			
		||||
             meta->sampler.type == TextureType::TextureCube);
 | 
			
		||||
 | 
			
		||||
        std::string expr = "texture";
 | 
			
		||||
 | 
			
		||||
        if (workaround_lod_array_shadow_as_grad) {
 | 
			
		||||
            expr += "Grad";
 | 
			
		||||
        } else {
 | 
			
		||||
            expr += function_suffix;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::string expr = "texture" + function_suffix;
 | 
			
		||||
        if (!meta->aoffi.empty()) {
 | 
			
		||||
            expr += "Offset";
 | 
			
		||||
        } else if (!meta->ptp.empty()) {
 | 
			
		||||
@ -1415,6 +1430,16 @@ private:
 | 
			
		||||
            expr += ')';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (workaround_lod_array_shadow_as_grad) {
 | 
			
		||||
            switch (meta->sampler.type) {
 | 
			
		||||
            case TextureType::Texture2D:
 | 
			
		||||
                return expr + ", vec2(0.0), vec2(0.0))";
 | 
			
		||||
            case TextureType::TextureCube:
 | 
			
		||||
                return expr + ", vec3(0.0), vec3(0.0))";
 | 
			
		||||
            }
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const auto& variant : extras) {
 | 
			
		||||
            if (const auto argument = std::get_if<TextureArgument>(&variant)) {
 | 
			
		||||
                expr += GenerateTextureArgument(*argument);
 | 
			
		||||
@ -2041,8 +2066,19 @@ private:
 | 
			
		||||
        const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
 | 
			
		||||
        ASSERT(meta);
 | 
			
		||||
 | 
			
		||||
        std::string expr = GenerateTexture(
 | 
			
		||||
            operation, "Lod", {TextureArgument{Type::Float, meta->lod}, TextureOffset{}});
 | 
			
		||||
        std::string expr{};
 | 
			
		||||
 | 
			
		||||
        if (!device.HasTextureShadowLod() && meta->sampler.is_shadow &&
 | 
			
		||||
            ((meta->sampler.type == TextureType::Texture2D && meta->sampler.is_array) ||
 | 
			
		||||
             meta->sampler.type == TextureType::TextureCube)) {
 | 
			
		||||
            LOG_ERROR(Render_OpenGL,
 | 
			
		||||
                      "Device lacks GL_EXT_texture_shadow_lod, using textureGrad as a workaround");
 | 
			
		||||
            expr = GenerateTexture(operation, "Lod", {});
 | 
			
		||||
        } else {
 | 
			
		||||
            expr = GenerateTexture(operation, "Lod",
 | 
			
		||||
                                   {TextureArgument{Type::Float, meta->lod}, TextureOffset{}});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (meta->sampler.is_shadow) {
 | 
			
		||||
            expr = "vec4(" + expr + ')';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user