mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Feat] (MG_Util/ShaderCompiler): extract global UBO offset from GL plain uniforms
This commit is contained in:
@@ -287,6 +287,21 @@ TEST_F(ProgramTest, DecompProgram) {
|
||||
}
|
||||
}
|
||||
|
||||
auto ubo0 = sessions[0].GetShaderInterface(SPVC_RESOURCE_TYPE_UNIFORM_BUFFER);
|
||||
auto ubo1 = sessions[1].GetShaderInterface(SPVC_RESOURCE_TYPE_UNIFORM_BUFFER);
|
||||
auto& meta0 = sessions[0].GetMetadata();
|
||||
auto& meta1 = sessions[1].GetMetadata();
|
||||
|
||||
for (auto& [name, offset] : meta0.plainUniformOffsetsInUBO) {
|
||||
printf("%s: \t%u\n", name.c_str(), offset);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
for (auto& [name, offset] : meta1.plainUniformOffsetsInUBO) {
|
||||
printf("%s: \t%u\n", name.c_str(), offset);
|
||||
}
|
||||
|
||||
EXPECT_EQ(meta0.plainUniformOffsetsInUBO.size(), meta1.plainUniformOffsetsInUBO.size());
|
||||
for (auto& [name, offset] : meta0.plainUniformOffsetsInUBO) {
|
||||
EXPECT_EQ(offset, meta1.plainUniformOffsetsInUBO.at(name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace MobileGL {
|
||||
tshader->setAutoMapLocations(true);
|
||||
tshader->setAutoMapBindings(true);
|
||||
tshader->setEnvInputVulkanRulesRelaxed(); // using EXT_vulkan_glsl_relaxed for gl_VertexID and gl_InstanceID?
|
||||
tshader->setGlobalUniformBlockName("MGL_GLOBAL_UBO");
|
||||
tshader->setGlobalUniformBlockName(GLOBAL_UBO_NAME);
|
||||
if (!tshader->parse(&GetTBuiltInResourceInstance(), 150, ECoreProfile,
|
||||
/*forceDefaultVersionAndProfile: */false,
|
||||
/*forwardCompatible: */true, EShMsgDefault)) {
|
||||
|
||||
@@ -54,32 +54,52 @@ namespace ShaderTranspiler {
|
||||
var.name = list[i].name;
|
||||
var.location = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationLocation);
|
||||
variables.push_back(var);
|
||||
|
||||
if (resource_type == SPVC_RESOURCE_TYPE_UNIFORM_BUFFER) {
|
||||
spvc_type type = spvc_compiler_get_type_handle(compiler, list[i].base_type_id);
|
||||
size_t num_members = spvc_type_get_num_member_types(type);
|
||||
printf("uniform %s {\n", var.name.c_str());
|
||||
for (size_t j = 0; j < num_members; ++j) {
|
||||
const char *memberName = spvc_compiler_get_member_name(compiler, list[i].base_type_id, j);
|
||||
// auto memberTypeId = spvc_type_get_member_type(type, j);
|
||||
// auto memberType = spvc_compiler_get_type_handle(compiler, memberTypeId);
|
||||
|
||||
unsigned memberOffset = 0;
|
||||
spvc_compiler_type_struct_member_offset(compiler, type, j, &memberOffset);
|
||||
printf("\b%s; // %u\n", memberName, memberOffset);
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
}
|
||||
std::sort(variables.begin(), variables.end());
|
||||
return variables;
|
||||
}
|
||||
|
||||
spvc_result SpvcSession::Compile(const char** result) const {
|
||||
return spvc_compiler_compile(compiler, result);
|
||||
spvc_result SpvcSession::Compile(const char** result) {
|
||||
SPVC_CHK_INIT
|
||||
SPVC_CHK_RESULT(spvc_compiler_compile(compiler, result));
|
||||
SPVC_CHK_RESULT(ParseMetaData());
|
||||
SPVC_CHK_RETURN
|
||||
}
|
||||
|
||||
spvc_result SpvcSession::ParseMetaData() {
|
||||
SPVC_CHK_INIT
|
||||
|
||||
metadata = SpvcMetadata();
|
||||
|
||||
const spvc_reflected_resource *list = nullptr;
|
||||
size_t count = 0;
|
||||
|
||||
SPVC_CHK_RESULT(
|
||||
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count);
|
||||
)
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (spvc_compiler_has_decoration(compiler, list[i].id, SpvDecorationBuiltIn)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(list[i].name, GLOBAL_UBO_NAME) == 0) {
|
||||
spvc_type type = spvc_compiler_get_type_handle(compiler, list[i].base_type_id);
|
||||
size_t num_members = spvc_type_get_num_member_types(type);
|
||||
for (size_t j = 0; j < num_members; ++j) {
|
||||
const char *memberName = spvc_compiler_get_member_name(compiler, list[i].base_type_id, j);
|
||||
|
||||
unsigned memberOffset = 0;
|
||||
SPVC_CHK_RESULT(spvc_compiler_type_struct_member_offset(compiler, type, j, &memberOffset);)
|
||||
metadata.plainUniformOffsetsInUBO[memberName] = memberOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
SPVC_CHK_RETURN
|
||||
}
|
||||
|
||||
const SpvcMetadata& SpvcSession::GetMetadata() const {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
const char* SpvcSession::GetLastErrorString() const {
|
||||
return spvc_context_get_last_error_string(context);
|
||||
|
||||
@@ -7,9 +7,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SPVC_CHK_INIT \
|
||||
auto __r = SPVC_SUCCESS;
|
||||
|
||||
#define SPVC_CHK_RESULT(res) \
|
||||
__r = res; \
|
||||
if (__r != SPVC_SUCCESS) { \
|
||||
return __r; \
|
||||
}
|
||||
|
||||
#define SPVC_CHK_RETURN \
|
||||
return __r;
|
||||
|
||||
namespace MobileGL {
|
||||
namespace MG_Util {
|
||||
namespace ShaderTranspiler {
|
||||
struct SpvcMetadata {
|
||||
UnorderedMap<String, unsigned> plainUniformOffsetsInUBO;
|
||||
};
|
||||
|
||||
class SpvcSession {
|
||||
public:
|
||||
SpvcSession() {}
|
||||
@@ -29,15 +45,21 @@ namespace ShaderTranspiler {
|
||||
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 Compile(const char** result) const;
|
||||
spvc_result Compile(const char** result);
|
||||
const SpvcMetadata& GetMetadata() const;
|
||||
const char* GetLastErrorString() const;
|
||||
|
||||
private:
|
||||
// Should be called once, and only once, for every SPIR-V binary
|
||||
spvc_result ParseMetaData();
|
||||
|
||||
spvc_context context = nullptr;
|
||||
spvc_parsed_ir ir = nullptr;
|
||||
spvc_compiler compiler = nullptr;
|
||||
spvc_compiler_options compiler_options = nullptr;
|
||||
spvc_resources resources = nullptr;
|
||||
|
||||
SpvcMetadata metadata;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
namespace MobileGL {
|
||||
namespace MG_Util {
|
||||
namespace ShaderTranspiler {
|
||||
inline const char* GLOBAL_UBO_NAME = "MGL_GLOBAL_UBO";
|
||||
|
||||
struct EmptyType {};
|
||||
|
||||
struct ShaderAttrib {
|
||||
|
||||
Reference in New Issue
Block a user