[Fix] (MG_Backend/DirectVulkan): more flexible ResolveSamplerDescriptor

This commit is contained in:
2026-05-05 17:13:35 +08:00
parent 94e93b171c
commit 7716a8e05d
@@ -180,30 +180,41 @@ namespace MobileGL::MG_Backend::DirectVulkan {
"ResolveSamplerDescriptor: sampler binding %u name lookup out of range", binding); "ResolveSamplerDescriptor: sampler binding %u name lookup out of range", binding);
SharedPtr<MG_State::GLState::ITextureObject> texture; SharedPtr<MG_State::GLState::ITextureObject> texture;
const Bool resolvedTexture = ResolveSamplerTexture(program, programObj, binding, texture); const Bool resolvedTexture = ResolveSamplerTexture(program, programObj, binding, texture);
MOBILEGL_ASSERT(resolvedTexture, if (!resolvedTexture) {
"ResolveSamplerDescriptor: failed to resolve sampler texture for binding %u ('%s')", binding, MGLOG_E("ResolveSamplerDescriptor: failed to resolve sampler texture for binding %u ('%s')", binding,
programObj.samplerNameByBinding[binding].c_str()); programObj.samplerNameByBinding[binding].c_str());
return false;
}
const Int location = programObj.samplerUniformLocationByBinding[binding]; const Int location = programObj.samplerUniformLocationByBinding[binding];
const Int unit = ResolveSamplerUnitIndex(program, location, binding); const Int unit = ResolveSamplerUnitIndex(program, location, binding);
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit); auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
const auto samplerOverride = textureUnit.GetSamplerObject(); const auto samplerOverride = textureUnit.GetSamplerObject();
MOBILEGL_ASSERT(texture != nullptr, if (texture == nullptr) {
"ResolveSamplerDescriptor: sampler binding %u ('%s') resolved null texture (location=%d unit=%d target=%d)", MGLOG_E(
binding, programObj.samplerNameByBinding[binding].c_str(), location, unit, "ResolveSamplerDescriptor: sampler binding %u ('%s') resolved null texture (location=%d unit=%d target=%d)",
static_cast<Int>(programObj.samplerTextureTargetByBinding[binding])); binding, programObj.samplerNameByBinding[binding].c_str(), location, unit,
static_cast<Int>(programObj.samplerTextureTargetByBinding[binding]));
return false;
}
const MG_State::GLState::SamplerObject* samplerToUse = const MG_State::GLState::SamplerObject* samplerToUse =
samplerOverride ? samplerOverride.get() : texture->GetSamplerObject().get(); samplerOverride ? samplerOverride.get() : texture->GetSamplerObject().get();
MOBILEGL_ASSERT(samplerToUse != nullptr, if (samplerToUse == nullptr) {
"ResolveSamplerDescriptor: sampler binding %u ('%s') has no sampler object (textureId=%d location=%d unit=%d)", MGLOG_E(
binding, programObj.samplerNameByBinding[binding].c_str(), texture->GetExternalIndex(), location, "ResolveSamplerDescriptor: sampler binding %u ('%s') has no sampler object (textureId=%d location=%d unit=%d)",
unit); binding, programObj.samplerNameByBinding[binding].c_str(), texture->GetExternalIndex(), location,
unit);
return false;
}
VkTextureManager::TextureResource* resource = m_textureManager->SyncTextureAndGetDescriptor(*texture); VkTextureManager::TextureResource* resource = m_textureManager->SyncTextureAndGetDescriptor(*texture);
MOBILEGL_ASSERT(resource != nullptr, if (resource == nullptr) {
"ResolveSamplerDescriptor: sampler binding %u ('%s') failed to create/sync texture resource (textureId=%d target=%d location=%d unit=%d)", MGLOG_E(
binding, programObj.samplerNameByBinding[binding].c_str(), texture->GetExternalIndex(), "ResolveSamplerDescriptor: sampler binding %u ('%s') failed to create/sync texture resource (textureId=%d target=%d location=%d unit=%d)",
static_cast<Int>(texture->GetTarget()), location, unit); binding, programObj.samplerNameByBinding[binding].c_str(), texture->GetExternalIndex(),
static_cast<Int>(texture->GetTarget()), location, unit);
return false;
}
if (!IsValidSampledImageLayout(resource->layout)) { if (!IsValidSampledImageLayout(resource->layout)) {
auto drawFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); auto drawFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
FramebufferAttachmentType attachmentType = FramebufferAttachmentType::None; FramebufferAttachmentType attachmentType = FramebufferAttachmentType::None;
@@ -279,9 +290,26 @@ namespace MobileGL::MG_Backend::DirectVulkan {
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit); auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
const TextureTarget preferredTarget = programObj.samplerTextureTargetByBinding[binding]; const TextureTarget preferredTarget = programObj.samplerTextureTargetByBinding[binding];
outTexture = textureUnit.GetBindingSlot(preferredTarget).GetBoundObject(); outTexture = textureUnit.GetBindingSlot(preferredTarget).GetBoundObject();
MOBILEGL_ASSERT(outTexture != nullptr,
"ResolveSamplerTexture: no texture bound for sampler binding=%u location=%d unit=%d target=%d", if (!outTexture) {
binding, location, unit, static_cast<Int>(preferredTarget)); for (const auto& bindingSlot : textureUnit.GetAllBindingSlots()) {
const auto& fallbackTexture = bindingSlot.GetBoundObject();
if (!fallbackTexture) {
continue;
}
outTexture = fallbackTexture;
MGLOG_D(
"ResolveSamplerTexture: falling back to bound textureId=%d for sampler binding=%u location=%d unit=%d target=%d",
outTexture->GetExternalIndex(), binding, location, unit, static_cast<Int>(preferredTarget));
break;
}
}
if (!outTexture) {
MGLOG_E("ResolveSamplerTexture: no texture bound for sampler binding=%u location=%d unit=%d target=%d",
binding, location, unit, static_cast<Int>(preferredTarget));
return false;
}
return outTexture != nullptr; return outTexture != nullptr;
} }