mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
Merge branch 'dev' into Feat/Backend-Direct-GLES
This commit is contained in:
@@ -473,7 +473,7 @@ namespace MobileGL {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location >= programObject->GetUniformCount() || location < -1) {
|
if (location > programObject->GetMaxUniformLocation() || location < -1) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
|||||||
@@ -69,32 +69,63 @@ namespace MobileGL {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------ Uniforms (GL Plain) ----------------
|
||||||
|
// Allocate uniform locations
|
||||||
m_activeUniformCount = m_program->getNumUniformVariables();
|
m_activeUniformCount = m_program->getNumUniformVariables();
|
||||||
for (int i = 0; i < m_activeUniformCount; i++) {
|
for (int i = 0; i < m_activeUniformCount; i++) {
|
||||||
auto& uniform = m_program->getUniform(i);
|
auto& uniform = m_program->getUniform(i);
|
||||||
auto location = uniform.layoutLocation();
|
auto location = uniform.layoutLocation();
|
||||||
if (location >= 0) {
|
if (location != 4095) {
|
||||||
m_maxUniformLocation = std::max(m_maxUniformLocation, location);
|
m_maxUniformLocation = std::max(m_maxUniformLocation, location);
|
||||||
}
|
}
|
||||||
m_uniformNameMaxLength = std::max(m_uniformNameMaxLength, (Int)uniform.name.length());
|
m_uniformNameMaxLength = std::max(m_uniformNameMaxLength, (Int)uniform.name.length());
|
||||||
m_uniformLocations[uniform.name] = location;
|
m_uniformLocations[uniform.name] = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_maxUniformLocation + 1 < m_activeUniformCount) {
|
||||||
|
// This means we have fewer than enough gaps to fit
|
||||||
|
// unallocated uniforms
|
||||||
|
m_maxUniformLocation = m_activeUniformCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// i-th elements refers to uniform at layout(location = i, ...)
|
||||||
|
// Be aware, there could be gaps in between these vectors
|
||||||
|
// Locations can be not sequential
|
||||||
m_uniformNames.resize(m_maxUniformLocation + 1);
|
m_uniformNames.resize(m_maxUniformLocation + 1);
|
||||||
m_uniformTypes.resize(m_maxUniformLocation + 1);
|
m_uniformTypes.resize(m_maxUniformLocation + 1, GL_ZERO);
|
||||||
m_uniformIsOpaqueType.resize(m_maxUniformLocation + 1);
|
m_uniformIsOpaqueType.resize(m_maxUniformLocation + 1);
|
||||||
m_uniformOffsets.resize(m_maxUniformLocation + 1);
|
m_uniformOffsets.resize(m_maxUniformLocation + 1);
|
||||||
m_uniformArraySizes.resize(m_maxUniformLocation + 1);
|
m_uniformArraySizes.resize(m_maxUniformLocation + 1);
|
||||||
|
|
||||||
|
Vector<int> unallocatedUniformIndex;
|
||||||
|
|
||||||
|
// Populate vector with already allocated location
|
||||||
for (int i = 0; i < m_activeUniformCount; i++) {
|
for (int i = 0; i < m_activeUniformCount; i++) {
|
||||||
auto& uniform = m_program->getUniform(i);
|
auto& uniform = m_program->getUniform(i);
|
||||||
auto location = uniform.layoutLocation();
|
auto location = uniform.layoutLocation();
|
||||||
if (location >= 0 && location < (int)m_uniformNames.size()) {
|
if (location >= m_uniformNames.size()) {
|
||||||
|
unallocatedUniformIndex.emplace_back(i);
|
||||||
|
continue; // will allocate unallocated uniforms later
|
||||||
|
}
|
||||||
m_uniformNames[location] = uniform.name;
|
m_uniformNames[location] = uniform.name;
|
||||||
m_uniformTypes[location] = uniform.glDefineType;
|
m_uniformTypes[location] = uniform.glDefineType;
|
||||||
m_uniformIsOpaqueType[location] = uniform.getType()->isOpaque();
|
m_uniformIsOpaqueType[location] = uniform.getType()->isOpaque();
|
||||||
m_uniformArraySizes[location] = uniform.size;
|
m_uniformArraySizes[location] = uniform.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SizeT locNeedle = 0;
|
||||||
|
for (auto index : unallocatedUniformIndex) {
|
||||||
|
auto& uniform = m_program->getUniform(index);
|
||||||
|
for (; locNeedle <= m_maxUniformLocation; locNeedle++) {
|
||||||
|
if (m_uniformTypes[locNeedle] != GL_ZERO) continue;
|
||||||
|
// Found a vacant location at locNeedle
|
||||||
|
m_uniformNames[locNeedle] = uniform.name;
|
||||||
|
m_uniformTypes[locNeedle] = uniform.glDefineType;
|
||||||
|
m_uniformIsOpaqueType[locNeedle] = uniform.getType()->isOpaque();
|
||||||
|
m_uniformArraySizes[locNeedle] = uniform.size;
|
||||||
|
m_uniformLocations[uniform.name] = locNeedle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int inCount = m_program->getNumPipeInputs();
|
int inCount = m_program->getNumPipeInputs();
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ namespace MobileGL {
|
|||||||
Uint GetMaxUniformLocation() const { return m_maxUniformLocation; }
|
Uint GetMaxUniformLocation() const { return m_maxUniformLocation; }
|
||||||
Int GetUniformLocation(const String& name) {
|
Int GetUniformLocation(const String& name) {
|
||||||
const auto it = m_uniformLocations.find(name);
|
const auto it = m_uniformLocations.find(name);
|
||||||
return (it == m_uniformLocations.end()) ? -1 : (Int)it->second;
|
if (it == m_uniformLocations.end()) return -1;
|
||||||
|
return (Int)it->second;
|
||||||
}
|
}
|
||||||
GLenum GetUniformType(Uint index) const { return m_uniformTypes[index]; }
|
GLenum GetUniformType(Uint index) const { return m_uniformTypes[index]; }
|
||||||
|
|
||||||
|
|||||||
@@ -207,6 +207,10 @@ TEST_F(ProgramTest, UniformMatrixFunctions) {
|
|||||||
|
|
||||||
UseProgram(program);
|
UseProgram(program);
|
||||||
|
|
||||||
|
int uniformCount = 0;
|
||||||
|
GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
|
||||||
|
ASSERT_LT(uniformCount, 4000);
|
||||||
|
|
||||||
// Test UniformMatrix2fv
|
// Test UniformMatrix2fv
|
||||||
auto locProjMat = GetUniformLocation(program, "ProjMat");
|
auto locProjMat = GetUniformLocation(program, "ProjMat");
|
||||||
ASSERT_NE(locProjMat, -1);
|
ASSERT_NE(locProjMat, -1);
|
||||||
@@ -268,6 +272,10 @@ TEST_F(ProgramTest, UniformMatrixTranspose) {
|
|||||||
|
|
||||||
UseProgram(program);
|
UseProgram(program);
|
||||||
|
|
||||||
|
int uniformCount = 0;
|
||||||
|
GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
|
||||||
|
ASSERT_LT(uniformCount, 4000);
|
||||||
|
|
||||||
// Test 2x2 matrix transpose
|
// Test 2x2 matrix transpose
|
||||||
auto locMat2 = GetUniformLocation(program, "TestMat2");
|
auto locMat2 = GetUniformLocation(program, "TestMat2");
|
||||||
ASSERT_NE(locMat2, -1);
|
ASSERT_NE(locMat2, -1);
|
||||||
@@ -428,6 +436,10 @@ TEST_F(ProgramTest, UniformLocationGaps) {
|
|||||||
|
|
||||||
UseProgram(program);
|
UseProgram(program);
|
||||||
|
|
||||||
|
int uniformCount = 0;
|
||||||
|
GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
|
||||||
|
ASSERT_LT(uniformCount, 4000);
|
||||||
|
|
||||||
// Test that uniform locations are correctly assigned even with gaps
|
// Test that uniform locations are correctly assigned even with gaps
|
||||||
// ProjMat is at location 0
|
// ProjMat is at location 0
|
||||||
ASSERT_EQ(GetUniformLocation(program, "ProjMat"), 0);
|
ASSERT_EQ(GetUniformLocation(program, "ProjMat"), 0);
|
||||||
@@ -480,3 +492,75 @@ TEST_F(ProgramTest, UniformLocationGaps) {
|
|||||||
ASSERT_EQ(redVal[1], 3.0);
|
ASSERT_EQ(redVal[1], 3.0);
|
||||||
ASSERT_EQ(redVal[2], 5.0);
|
ASSERT_EQ(redVal[2], 5.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* mc_position_tex_fs = R"(#version 150
|
||||||
|
|
||||||
|
uniform sampler2D Sampler0;
|
||||||
|
|
||||||
|
uniform vec4 ColorModulator;
|
||||||
|
|
||||||
|
in vec2 texCoord0;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = texture(Sampler0, texCoord0);
|
||||||
|
if (color.a == 0.0) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
fragColor = color * ColorModulator;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* mc_position_tex_vs = R"(#version 150
|
||||||
|
|
||||||
|
in vec3 Position;
|
||||||
|
in vec2 UV0;
|
||||||
|
|
||||||
|
uniform mat4 ModelViewMat;
|
||||||
|
uniform mat4 ProjMat;
|
||||||
|
|
||||||
|
out vec2 texCoord0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
|
||||||
|
|
||||||
|
texCoord0 = UV0;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
TEST_F(ProgramTest, MinecraftPositionTex) {
|
||||||
|
char infoLog[1024] = "";
|
||||||
|
|
||||||
|
GLuint vs = CreateShader(GL_VERTEX_SHADER);
|
||||||
|
ShaderSource(vs, 1, &mc_position_tex_vs, NULL);
|
||||||
|
CompileShader(vs);
|
||||||
|
GLint vsStatus = GL_FALSE;
|
||||||
|
GetShaderiv(vs, GL_COMPILE_STATUS, &vsStatus);
|
||||||
|
GetShaderInfoLog(vs, 1024, nullptr, infoLog);
|
||||||
|
ASSERT_EQ(vsStatus, GL_TRUE) << infoLog;
|
||||||
|
|
||||||
|
GLuint fs = CreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
ShaderSource(fs, 1, &mc_position_tex_fs, NULL);
|
||||||
|
CompileShader(fs);
|
||||||
|
GLint fsStatus = GL_FALSE;
|
||||||
|
GetShaderiv(fs, GL_COMPILE_STATUS, &fsStatus);
|
||||||
|
GetShaderInfoLog(fs, 1024, nullptr, infoLog);
|
||||||
|
ASSERT_EQ(fsStatus, GL_TRUE) << infoLog;
|
||||||
|
|
||||||
|
GLuint program = CreateProgram();
|
||||||
|
AttachShader(program, vs);
|
||||||
|
AttachShader(program, fs);
|
||||||
|
|
||||||
|
LinkProgram(program);
|
||||||
|
|
||||||
|
UseProgram(program);
|
||||||
|
|
||||||
|
int uniformCount = 0;
|
||||||
|
GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
|
||||||
|
ASSERT_LT(uniformCount, 4000);
|
||||||
|
|
||||||
|
int sampler0Loc = GetUniformLocation(program, "Sampler0");
|
||||||
|
ASSERT_GE(sampler0Loc, 0);
|
||||||
|
ASSERT_LT(sampler0Loc, 4000);
|
||||||
|
}
|
||||||
|
|||||||
@@ -443,6 +443,7 @@ namespace MobileGL {
|
|||||||
static const char* EGLLibs[] = {"libEGL", nullptr};
|
static const char* EGLLibs[] = {"libEGL", nullptr};
|
||||||
|
|
||||||
void* OpenLib(const char** names, const char* override) {
|
void* OpenLib(const char** names, const char* override) {
|
||||||
|
#if !defined(__WIN32) && !defined(_WIN32)
|
||||||
void* lib = nullptr;
|
void* lib = nullptr;
|
||||||
|
|
||||||
char path_name[PATH_MAX + 1];
|
char path_name[PATH_MAX + 1];
|
||||||
@@ -464,6 +465,9 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lib;
|
return lib;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadLibs() {
|
void LoadLibs() {
|
||||||
@@ -473,7 +477,11 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* ProcAddress(void* lib, const char* name) {
|
void* ProcAddress(void* lib, const char* name) {
|
||||||
|
#if !defined(__WIN32) && !defined(_WIN32)
|
||||||
return dlsym(lib, name);
|
return dlsym(lib, name);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitGLESCapabilities() {
|
void InitGLESCapabilities() {
|
||||||
|
|||||||
Reference in New Issue
Block a user