mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 21:28:32 +09:00
[Feat]: implement glBindVertexAttribLocation in DirectGLES backend (fixing OptiFine?)
This commit is contained in:
@@ -501,6 +501,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
auto& spirvCode = shaderSpirvs[index];
|
||||
|
||||
MG_Util::ShaderTranspiler::SpvcSession spvcSession(spirvCode);
|
||||
if (glShaderType == GL_VERTEX_SHADER) {
|
||||
spvcSession.SetVertexAttribLocation(stateProgramObject->GetAttribLocationMap());
|
||||
}
|
||||
|
||||
spvc_compiler_options options;
|
||||
spvcSession.CreateOptions(&options);
|
||||
|
||||
@@ -195,6 +195,10 @@ namespace MobileGL {
|
||||
std::swap(m_attribs[location], m_attribs[idx]);
|
||||
std::swap(m_attribTypes[location], m_attribTypes[idx]);
|
||||
}
|
||||
|
||||
for (SizeT idx = 0; idx < m_attribs.size(); ++idx) {
|
||||
m_attribLocation[m_attribs[idx]] = idx;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- UBO ----------
|
||||
@@ -207,7 +211,6 @@ namespace MobileGL {
|
||||
m_uniformBlockIndex[ubo.name] = ubo.getBinding();
|
||||
m_uniformBlockIndexInTProgram[ubo.getBinding()] = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ProgramObject::GenerateBinary() {
|
||||
@@ -244,7 +247,9 @@ namespace MobileGL {
|
||||
assert(binaryResult);
|
||||
m_generatedSpirv = Move(binaryResult.value());
|
||||
|
||||
for (auto spv : m_generatedSpirv) {
|
||||
for (SizeT i = 0; i < m_generatedSpirv.size(); i++) {
|
||||
auto& spv = m_generatedSpirv[i];
|
||||
auto shaderType = shaderTypes[i];
|
||||
SpvcSession session(spv);
|
||||
auto result = session.ParseMetaData();
|
||||
if (result < 0) {
|
||||
|
||||
@@ -108,6 +108,8 @@ namespace MobileGL {
|
||||
|
||||
Uint GetExternalIndex() const { return m_externalIndex; }
|
||||
|
||||
const UnorderedMap<String, Uint>& GetAttribLocationMap() const { return m_attribLocation; }
|
||||
|
||||
private:
|
||||
void DoReflection();
|
||||
void GenerateBinary();
|
||||
@@ -124,6 +126,8 @@ namespace MobileGL {
|
||||
UnorderedMap<String, Uint> m_explicitAttribLocations;
|
||||
Vector<String> m_attribs;
|
||||
Vector<GLenum> m_attribTypes;
|
||||
// For SpvcSession::SetVertexAttribLocation()
|
||||
UnorderedMap<String, Uint> m_attribLocation;
|
||||
|
||||
// Uniforms
|
||||
UnorderedMap<String, Uint> m_uniformLocations;
|
||||
|
||||
@@ -19,7 +19,7 @@ TEST_F(ProgramTest, Sanity) {
|
||||
|
||||
const char* vsSrc = R"(#version 460
|
||||
|
||||
layout (location = 0) in vec4 Position;
|
||||
layout (location = 2) in vec4 Position;
|
||||
in float fIn4;
|
||||
in float fIn2;
|
||||
in float fIn5;
|
||||
@@ -146,7 +146,7 @@ TEST_F(ProgramTest, CompileAndLink) {
|
||||
GetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformNameMaxLength);
|
||||
ASSERT_EQ(uniformNameMaxLength, 12);
|
||||
|
||||
ASSERT_EQ(GetAttribLocation(program, "Position"), 0);
|
||||
ASSERT_EQ(GetAttribLocation(program, "Position"), 2);
|
||||
ASSERT_EQ(GetAttribLocation(program, "fIn1"), 1);
|
||||
ASSERT_EQ(GetAttribLocation(program, "fIn3"), 3);
|
||||
ASSERT_EQ(GetAttribLocation(program, "fIn5"), 5);
|
||||
@@ -169,6 +169,36 @@ TEST_F(ProgramTest, CompileAndLink) {
|
||||
int intVal;
|
||||
GetUniformiv(program, locInt, &intVal);
|
||||
EXPECT_EQ(intVal, 114514);
|
||||
|
||||
auto programObj = MG_State::pGLContext->GetProgramObject(program);
|
||||
auto& shaderSpirvs = programObj->GetGeneratedSpirv();
|
||||
for (int index = 0; index < shaderSpirvs.size(); ++index) {
|
||||
String source;
|
||||
auto& spirvCode = shaderSpirvs[index];
|
||||
|
||||
MG_Util::ShaderTranspiler::SpvcSession spvcSession(spirvCode);
|
||||
|
||||
spvc_compiler_options options;
|
||||
spvcSession.CreateOptions(&options);
|
||||
|
||||
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, 320);
|
||||
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_TRUE);
|
||||
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, SPVC_FALSE);
|
||||
|
||||
spvcSession.SetOptions(options);
|
||||
|
||||
const char* result = nullptr;
|
||||
spvcSession.Compile(&result);
|
||||
|
||||
if (!result) {
|
||||
MG_Util::ShaderTranspiler::ResultInfo r;
|
||||
r.log += "Failed to compile the shader to GLSL: \n";
|
||||
r.log += spvcSession.GetLastErrorString();
|
||||
r.errc = -5;
|
||||
FAIL() << r.log;
|
||||
}
|
||||
printf("shader dump: \n%s\n", result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ProgramTest, UniformMatrixFunctions) {
|
||||
|
||||
@@ -60,6 +60,25 @@ namespace MobileGL {
|
||||
return variables;
|
||||
}
|
||||
|
||||
spvc_result SpvcSession::SetVertexAttribLocation(const UnorderedMap<String, Uint>& location) {
|
||||
// TODO: We should assert we're really dealing with vertex shader here
|
||||
|
||||
SPVC_CHK_INIT
|
||||
const spvc_reflected_resource *list = nullptr;
|
||||
size_t count = 0;
|
||||
SPVC_CHK_RESULT(spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STAGE_INPUT, &list, &count));
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
auto& resource = list[i];
|
||||
auto it = location.find(resource.name);
|
||||
if (it != location.end()) {
|
||||
// realize glBindVertexAttribLocation here
|
||||
// it->second should be the location explicitly requested
|
||||
spvc_compiler_set_decoration(compiler, resource.id, SpvDecorationLocation, it->second);
|
||||
}
|
||||
}
|
||||
SPVC_CHK_RETURN
|
||||
}
|
||||
|
||||
spvc_result SpvcSession::Compile(const char** result) {
|
||||
SPVC_CHK_INIT
|
||||
SPVC_CHK_RESULT(spvc_compiler_compile(compiler, result));
|
||||
|
||||
@@ -73,6 +73,7 @@ namespace MobileGL {
|
||||
spvc_result CreateOptions(spvc_compiler_options* options);
|
||||
spvc_result SetOptions(spvc_compiler_options options);
|
||||
Vector<InterfaceVariable> GetShaderInterface(spvc_resource_type resource_type) const;
|
||||
spvc_result SetVertexAttribLocation(const UnorderedMap<String, Uint>& location);
|
||||
spvc_result Compile(const char** result);
|
||||
const SpvcMetadata& GetMetadata() const;
|
||||
const char* GetLastErrorString() const;
|
||||
|
||||
Reference in New Issue
Block a user