Multiple textures are rendered incorrectly on AMD

Hello.
I have some problem with AMD graphics card. I have a batch renderer and it renders text


I have tried to use OpenGL 4.6 and 3.0, the result is the same.
I have tried AMD radeon HD 6770, 6850, 5770 and the result is the same.
On GTX 1050 it renders as it should.
Does anybody know how to fix this?

Shader

#shader vertex
#version 330 core

layout(location = 0) in vec4 positionA;
layout(location = 1) in vec2 uvA;
layout(location = 2) in int staticA;
layout(location = 3) in vec4 colorA;
layout(location = 4) in float isGuiA;
layout(location = 5) in float texIndexA;

flat out int texIndex;
flat out int isGui;
out vec4 color;
out vec2 uv;

uniform mat4 u_ViewProjection;
uniform mat4 u_Projection;

void main()
{
	if (staticA == 0)
	{
		gl_Position = u_ViewProjection * positionA;
	}
	else if (staticA > 1) 
	{
		gl_Position = u_Projection * positionA;
	}

	uv = uvA;
	color = colorA;
	isGui = int(isGuiA);
	texIndex = int(texIndexA);
};

#shader fragment
#version 330 core

layout(location = 0) out vec4 gl_FragColor;

flat in int texIndex;
flat in int isGui;
in vec4 color;
in vec2 uv;

uniform vec4 u_outlineColor;
uniform float u_width;
uniform float u_edge;
uniform float u_borderwidth;
uniform float u_borderedge;
uniform vec2 u_offset;
uniform sampler2D u_Texture[8];

void main() 
{
	if (isGui == 1) 
	{
		vec4 texColor = texture(u_Texture[texIndex], uv);
		gl_FragColor = color * texColor;
	}
	else if (isGui == 0)
	{
		float distance = 1.0 - texture(u_Texture[texIndex], uv).a;
		float alpha = 1.0 - smoothstep(u_width, u_width + u_edge, distance);
		float distance2 = 1.0 - texture(u_Texture[texIndex], uv + u_offset).a;
		float outlinealpha = 1.0 - smoothstep(u_borderwidth, u_borderwidth + u_borderedge, distance2);

		float overallalpha = alpha + (1.0 - alpha) * outlinealpha;
		vec3 overallcolor = mix(vec3(u_outlineColor.r, u_outlineColor.g, u_outlineColor.b), vec3(color.r, color.g, color.b), alpha / overallalpha);
		gl_FragColor = vec4(overallcolor, overallalpha);
	}
};

Batch renderer

Batch.h

#pragma once
#include "../pch.h"
#include "Gui/Character.h"
#include <array>
#include <mutex>

namespace OGL {

#define MAX_TEXTURE_SLOTS 8
#define RENDERER_MAX_SPRITES   1000
#define RENDERER_INDICES_SIZE  RENDERER_MAX_SPRITES * 6

	class Batch {
	private:

		struct TextVertex {
			glm::vec2 m_Vertex;
			glm::vec2 m_UV;
			int m_Static;
			glm::vec4 m_Color;
			float m_IsGui;
			float m_TexIndex;
		};

		struct VertAttribWrapper {
			std::array<uint32_t, MAX_TEXTURE_SLOTS> m_TextureSlots;
			unsigned int m_TextureSlotsIndex = 2;
			float m_TextureIndex = 0;

			TextVertex* m_BufferT = nullptr;
			TextVertex* m_BufferPtrT = nullptr;
			GLuint m_Vao;
			GLuint m_Vbo;
			IndexBuffer m_Ibo;

			~VertAttribWrapper()
			{
				glDeleteBuffers(1, &m_Vbo);
			}
		};

		VertAttribWrapper m_TextB;

		Shader* m_Shader = nullptr;
		const unsigned int maxTextureSlots = MAX_TEXTURE_SLOTS;
		void InitText();

		Batch();
		Batch(const Batch&) = delete;
		Batch& operator=(const Batch&) { return *this; }
		~Batch();
	public:

		Shader* m_TextShader = Shader::Get("Font");
		GLsizei m_TIndexCount = 0;

		static Batch& GetInstance();

		void Submit(Character* character);
		void Submit(float* mesh2D, glm::vec4 color, Texture* texture = nullptr);
		void FlushText(Shader* shader);

		void BeginText();
		void EndText();
	};

}

Batch.cpp

#include "Batch.h"
#include "Gui/Gui.h"
#include "../Utils.h"

using namespace OGL;

Batch::Batch()
{
	InitText();
	std::cout << BOLDGREEN << "Initialized Batch rendering" << RESET << std::endl;
}

Batch::~Batch()
{

}

Batch& Batch::GetInstance()
{
	static Batch instance;
	return instance;
}

void Batch::Submit(Character* c)
{

	if (m_TextB.m_TextureSlotsIndex > maxTextureSlots - 1)
	{
		EndText();
		FlushText(m_Shader);
		BeginText();
	}

	m_TextB.m_TextureIndex = 0.0f;

	//std::cout << "Batch " << c.position.x << "	" << c.position.y << std::endl;
	for (unsigned int i = 0; i < maxTextureSlots; i++)
	{
		if (m_TextB.m_TextureSlots[i] == c->m_Font->m_FontAtlas->m_RendererID)
		{
			m_TextB.m_TextureIndex = (float)i;
			break;
		}
	}

	if (m_TextB.m_TextureIndex == 0.0f)
	{
		m_TextB.m_TextureIndex = (float)m_TextB.m_TextureSlotsIndex;
		m_TextB.m_TextureSlots[m_TextB.m_TextureSlotsIndex] = c->m_Font->m_FontAtlas->m_RendererID;
		m_TextB.m_TextureSlotsIndex++;
	}

	m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[0] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[1]) * c->m_Scale.y + c->m_Position.y));
	m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[2], c->m_Mesh2D[3]);
	m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
	m_TextB.m_BufferT->m_Color = c->m_Color;
	m_TextB.m_BufferT->m_IsGui = 0.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[4] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[5]) * c->m_Scale.y + c->m_Position.y));
	m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[6], c->m_Mesh2D[7]);
	m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
	m_TextB.m_BufferT->m_Color = c->m_Color;
	m_TextB.m_BufferT->m_IsGui = 0.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[8] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[9]) * c->m_Scale.y + c->m_Position.y));
	m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[10], c->m_Mesh2D[11]);
	m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
	m_TextB.m_BufferT->m_Color = c->m_Color;
	m_TextB.m_BufferT->m_IsGui = 0.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[12] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[13]) * c->m_Scale.y + c->m_Position.y));
	m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[14], c->m_Mesh2D[15]);
	m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
	m_TextB.m_BufferT->m_Color = c->m_Color;
	m_TextB.m_BufferT->m_IsGui = 0.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TIndexCount += 6;
}

void Batch::Submit(float* mesh2D, glm::vec4 color, Texture* texture) 
{

	if (m_TextB.m_TextureSlotsIndex > maxTextureSlots - 1)
	{
		EndText();
		FlushText(m_Shader);
		BeginText();
	}

	m_TextB.m_TextureIndex = 0.0f;

	if (texture != nullptr)
	{
		for (unsigned int i = 0; i < maxTextureSlots; i++)
		{
			if (m_TextB.m_TextureSlots[i] == texture->m_RendererID)
			{
				m_TextB.m_TextureIndex = (float)i;
				break;
			}

		}
		if (m_TextB.m_TextureIndex == 0.0f) 
		{
			m_TextB.m_TextureIndex = (float)m_TextB.m_TextureSlotsIndex;
			m_TextB.m_TextureSlots[m_TextB.m_TextureSlotsIndex] = texture->m_RendererID;
			m_TextB.m_TextureSlotsIndex++;
		}
	}

	m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[0]), mesh2D[1]);
	m_TextB.m_BufferT->m_UV = glm::vec2(0,0);
	m_TextB.m_BufferT->m_Static = true;
	m_TextB.m_BufferT->m_Color = color;
	m_TextB.m_BufferT->m_IsGui = 1.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[2]), (mesh2D[3]));
	m_TextB.m_BufferT->m_UV = glm::vec2(1.0f, 0.0f);
	m_TextB.m_BufferT->m_Static = true;
	m_TextB.m_BufferT->m_Color = color;
	m_TextB.m_BufferT->m_IsGui = 1.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[4]), (mesh2D[5]));
	m_TextB.m_BufferT->m_UV = glm::vec2(1.0f, 1.0f);
	m_TextB.m_BufferT->m_Static = true;
	m_TextB.m_BufferT->m_Color = color;
	m_TextB.m_BufferT->m_IsGui = 1.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[6]), ((mesh2D[7])));
	m_TextB.m_BufferT->m_UV = glm::vec2(0.0f, 1.0f);
	m_TextB.m_BufferT->m_Static = true;
	m_TextB.m_BufferT->m_Color = color;
	m_TextB.m_BufferT->m_IsGui = 1.0f;
	m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
	m_TextB.m_BufferT++;

	m_TIndexCount += 6;
}

void Batch::BeginText() 
{
	m_TextB.m_BufferT = m_TextB.m_BufferPtrT;
	m_TIndexCount = 0;
}

void Batch::EndText() 
{
	uint32_t dataSize = (uint8_t*)m_TextB.m_BufferT - (uint8_t*)m_TextB.m_BufferPtrT;
	glBindBuffer(GL_ARRAY_BUFFER, m_TextB.m_Vbo);
	glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, m_TextB.m_BufferPtrT);
}

void Batch::FlushText(Shader* shader)
{
	glBindVertexArray(m_TextB.m_Vao);
	m_TextB.m_Ibo.Bind();
	shader->Bind();
	int samplers[MAX_TEXTURE_SLOTS];
	for (unsigned int i = 0; i < m_TextB.m_TextureSlotsIndex; i++)
	{
		glActiveTexture(GL_TEXTURE0 + i);
		glBindTexture(GL_TEXTURE_2D, m_TextB.m_TextureSlots[i]);
	}
	for (unsigned int i = 0; i < maxTextureSlots; i++)
	{
		samplers[i] = i;
	}

	Gui& g = Gui::GetInstance();
	shader->SetUniform1iv("u_Texture", samplers);
	shader->SetUniformMat4f("u_Projection", g.m_ViewProjecTionMat4RelatedToCamera);
	shader->SetUniformMat4f("u_ViewProjection", Window::GetInstance().GetCamera().GetViewProjectionMatrix());
	shader->SetUniform2fv("u_offset",       g.m_TextProps.m_ShadowOffset);
	shader->SetUniform1f("u_width",         g.m_TextProps.m_Width);
	shader->SetUniform1f("u_edge",          g.m_TextProps.m_Edge);
	shader->SetUniform1f("u_borderwidth",   g.m_TextProps.m_BorderWidth);
	shader->SetUniform1f("u_borderedge",    g.m_TextProps.m_BorderEdge);
	shader->SetUniform4fv("u_outlineColor", g.m_TextProps.m_OutLineColor);

	glDrawElements(GL_TRIANGLES, m_TIndexCount, GL_UNSIGNED_INT, NULL);
	shader->UnBind();
	m_TextB.m_Ibo.UnBind();
	glBindVertexArray(0);
	m_TextB.m_TextureSlotsIndex = 1;
	m_TextB.m_TextureSlots[0] = Texture::s_WhiteTexture->m_RendererID;
	for (unsigned int i = m_TextB.m_TextureSlotsIndex; i < MAX_TEXTURE_SLOTS; i++)
	{
		m_TextB.m_TextureSlots[i] = 0;
		glBindTexture(GL_TEXTURE_2D, 0);
	}
}

void Batch::InitText()
{
	glGenVertexArrays(1, &m_TextB.m_Vao);
	glBindVertexArray(m_TextB.m_Vao);

	glGenBuffers(1, &m_TextB.m_Vbo);
	glBindBuffer(GL_ARRAY_BUFFER, m_TextB.m_Vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(TextVertex) * 4 * RENDERER_MAX_SPRITES, NULL, GL_DYNAMIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_Vertex));

	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_UV));

	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_Static));

	glEnableVertexAttribArray(3);
	glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_Color));

	glEnableVertexAttribArray(4);
	glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_IsGui));

	glEnableVertexAttribArray(5);
	glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_TexIndex));

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	unsigned int indices[RENDERER_INDICES_SIZE];

	unsigned int offset = 0;
	for (unsigned int i = 0; i < RENDERER_INDICES_SIZE; i += 6)
	{
		indices[i + 0] = offset + 0;
		indices[i + 1] = offset + 1;
		indices[i + 2] = offset + 2;
		indices[i + 3] = offset + 2;
		indices[i + 4] = offset + 3;
		indices[i + 5] = offset + 0;

		offset += 4;
	}

	m_TextB.m_BufferPtrT = new TextVertex[RENDERER_MAX_SPRITES];
	m_TextB.m_Ibo.Init(indices, RENDERER_INDICES_SIZE);
	glBindVertexArray(0);

	m_TextB.m_TextureSlots[0] = Texture::s_WhiteTexture->m_RendererID;
	for (unsigned int i = 1; i < MAX_TEXTURE_SLOTS; i++)
	{
		m_TextB.m_TextureSlots[i] = 0;
	}

}

Call
Main.cpp

    OGL::Batch::GetInstance().m_TIndexCount = 0;
    OGL::Batch::GetInstance().BeginText();
    OnGuiRender();
    OGL::Batch::GetInstance().EndText();

    glDisable(GL_DEPTH_TEST);
    OGL::Batch::GetInstance().FlushText(fontShader);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);