mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] (MG_Backend/DirectVulkan): get global UBO binding
This commit is contained in:
@@ -356,6 +356,64 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool UniformDescriptorBinder::ReflectGlobalUboBinding(const MG_State::GLState::ProgramObject& program,
|
||||||
|
ProgramLayout& layout) const {
|
||||||
|
layout.globalUboBinding = -1;
|
||||||
|
|
||||||
|
const auto& spirv = program.GetGeneratedSpirv();
|
||||||
|
for (const auto& module : spirv) {
|
||||||
|
if (module.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
spvc_context context = nullptr;
|
||||||
|
spvc_parsed_ir ir = nullptr;
|
||||||
|
spvc_compiler compiler = nullptr;
|
||||||
|
spvc_resources resources = nullptr;
|
||||||
|
|
||||||
|
if (spvc_context_create(&context) != SPVC_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (spvc_context_parse_spirv(context, module.data(), module.size(), &ir) != SPVC_SUCCESS) {
|
||||||
|
spvc_context_destroy(context);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP,
|
||||||
|
&compiler) != SPVC_SUCCESS) {
|
||||||
|
spvc_context_destroy(context);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (spvc_compiler_create_shader_resources(compiler, &resources) != SPVC_SUCCESS) {
|
||||||
|
spvc_context_destroy(context);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const spvc_reflected_resource* list = nullptr;
|
||||||
|
size_t count = 0;
|
||||||
|
if (spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count) ==
|
||||||
|
SPVC_SUCCESS) {
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
const char* name = list[i].name ? list[i].name : "";
|
||||||
|
if (std::strstr(name, MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME) == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const Uint32 binding =
|
||||||
|
spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationBinding);
|
||||||
|
if (binding < m_maxBindings) {
|
||||||
|
layout.globalUboBinding = static_cast<Int>(binding);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spvc_context_destroy(context);
|
||||||
|
if (layout.globalUboBinding >= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Bool UniformDescriptorBinder::ResolveSamplerDescriptor(VkCommandBuffer commandBuffer,
|
Bool UniformDescriptorBinder::ResolveSamplerDescriptor(VkCommandBuffer commandBuffer,
|
||||||
const MG_State::GLState::ProgramObject& program,
|
const MG_State::GLState::ProgramObject& program,
|
||||||
const ProgramLayout& layout, Uint32 binding,
|
const ProgramLayout& layout, Uint32 binding,
|
||||||
@@ -429,6 +487,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
MGLOG_E("UniformDescriptorBinder::GetOrCreateProgramLayout failed: sampler reflection failed");
|
MGLOG_E("UniformDescriptorBinder::GetOrCreateProgramLayout failed: sampler reflection failed");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (!ReflectGlobalUboBinding(program, layout)) {
|
||||||
|
MGLOG_E("UniformDescriptorBinder::GetOrCreateProgramLayout failed: global UBO reflection failed");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<VkDescriptorSetLayoutBinding> bindings;
|
Vector<VkDescriptorSetLayoutBinding> bindings;
|
||||||
bindings.reserve(m_maxBindings);
|
bindings.reserve(m_maxBindings);
|
||||||
@@ -510,18 +572,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& blockName = program.GetUniformBlockName(blockIndex);
|
|
||||||
if (blockName == MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME) {
|
|
||||||
const void* globalUboData = program.GetUBOData();
|
|
||||||
const VkDeviceSize globalUboSize = static_cast<VkDeviceSize>(program.GetUBOSize());
|
|
||||||
if (globalUboData == nullptr || globalUboSize == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
outData[binding] = globalUboData;
|
|
||||||
outSizes[binding] = std::min(blockSize, globalUboSize);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding >= uniformBindingPointCount) {
|
if (binding >= uniformBindingPointCount) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -632,10 +682,20 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
if (kind == BindingKind::UniformBufferDynamic) {
|
if (kind == BindingKind::UniformBufferDynamic) {
|
||||||
const void* payload = bindingData[binding];
|
const void* payload = bindingData[binding];
|
||||||
VkDeviceSize payloadSize = bindingSizes[binding];
|
VkDeviceSize payloadSize = bindingSizes[binding];
|
||||||
|
if (payload == nullptr || payloadSize == 0) {
|
||||||
|
if (layout->globalUboBinding == static_cast<Int>(binding)) {
|
||||||
|
const void* globalUboData = program.GetUBOData();
|
||||||
|
const VkDeviceSize globalUboSize = static_cast<VkDeviceSize>(program.GetUBOSize());
|
||||||
|
if (globalUboData != nullptr && globalUboSize > 0) {
|
||||||
|
payload = globalUboData;
|
||||||
|
payloadSize = globalUboSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (payload == nullptr || payloadSize == 0) {
|
if (payload == nullptr || payloadSize == 0) {
|
||||||
payload = kFallbackData;
|
payload = kFallbackData;
|
||||||
payloadSize = sizeof(kFallbackData);
|
payloadSize = sizeof(kFallbackData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkDeviceSize payloadOffset = 0;
|
VkDeviceSize payloadOffset = 0;
|
||||||
if (!AllocateUploadRegion(frame, payloadSize, payloadOffset)) {
|
if (!AllocateUploadRegion(frame, payloadSize, payloadOffset)) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Vector<Uint32> dynamicBindings;
|
Vector<Uint32> dynamicBindings;
|
||||||
Vector<Int> samplerUniformLocationByBinding;
|
Vector<Int> samplerUniformLocationByBinding;
|
||||||
Vector<TextureTarget> samplerTextureTargetByBinding;
|
Vector<TextureTarget> samplerTextureTargetByBinding;
|
||||||
|
Int globalUboBinding = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VkDeviceSize AlignUp(VkDeviceSize value, VkDeviceSize alignment);
|
static VkDeviceSize AlignUp(VkDeviceSize value, VkDeviceSize alignment);
|
||||||
@@ -63,6 +64,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
static Bool IsSamplerUniformType(GLenum glType);
|
static Bool IsSamplerUniformType(GLenum glType);
|
||||||
static TextureTarget UniformTypeToTextureTarget(GLenum glType);
|
static TextureTarget UniformTypeToTextureTarget(GLenum glType);
|
||||||
Bool ReflectSamplerBindings(const MG_State::GLState::ProgramObject& program, ProgramLayout& layout) const;
|
Bool ReflectSamplerBindings(const MG_State::GLState::ProgramObject& program, ProgramLayout& layout) const;
|
||||||
|
Bool ReflectGlobalUboBinding(const MG_State::GLState::ProgramObject& program, ProgramLayout& layout) const;
|
||||||
Bool ResolveSamplerDescriptor(VkCommandBuffer commandBuffer, const MG_State::GLState::ProgramObject& program,
|
Bool ResolveSamplerDescriptor(VkCommandBuffer commandBuffer, const MG_State::GLState::ProgramObject& program,
|
||||||
const ProgramLayout& layout, Uint32 binding,
|
const ProgramLayout& layout, Uint32 binding,
|
||||||
VkDescriptorImageInfo& outImageInfo) const;
|
VkDescriptorImageInfo& outImageInfo) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user