mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Fix] (DirectVulkan): pass depth/stencil formats through sampled-view resolution so D24S8/D32FS8 samplers stop dropping draws, and memoize per-binding view-format resolution
This commit is contained in:
@@ -298,8 +298,23 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// descriptor valid.
|
// descriptor valid.
|
||||||
const Bool forceNearestFiltering = numericDomain == SamplerNumericDomain::SignedInteger ||
|
const Bool forceNearestFiltering = numericDomain == SamplerNumericDomain::SignedInteger ||
|
||||||
numericDomain == SamplerNumericDomain::UnsignedInteger;
|
numericDomain == SamplerNumericDomain::UnsignedInteger;
|
||||||
const VkFormat sampledViewFormat =
|
SamplerResolveMemo* viewFormatMemo =
|
||||||
|
binding < m_samplerResolveMemo.size() ? &m_samplerResolveMemo[binding] : nullptr;
|
||||||
|
VkFormat sampledViewFormat;
|
||||||
|
if (viewFormatMemo != nullptr && viewFormatMemo->viewFormatValid &&
|
||||||
|
viewFormatMemo->viewFormatSource == resource->format &&
|
||||||
|
viewFormatMemo->viewFormatDomain == numericDomain) {
|
||||||
|
sampledViewFormat = viewFormatMemo->viewFormat;
|
||||||
|
} else {
|
||||||
|
sampledViewFormat =
|
||||||
VkTextureManager::ResolveSampledImageViewFormat(resource->format, numericDomain);
|
VkTextureManager::ResolveSampledImageViewFormat(resource->format, numericDomain);
|
||||||
|
if (viewFormatMemo != nullptr) {
|
||||||
|
viewFormatMemo->viewFormatSource = resource->format;
|
||||||
|
viewFormatMemo->viewFormatDomain = numericDomain;
|
||||||
|
viewFormatMemo->viewFormat = sampledViewFormat;
|
||||||
|
viewFormatMemo->viewFormatValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (sampledViewFormat == VK_FORMAT_UNDEFINED) {
|
if (sampledViewFormat == VK_FORMAT_UNDEFINED) {
|
||||||
MGLOG_E("ResolveSamplerDescriptor: no compatible sampled view for binding=%u ('%s') "
|
MGLOG_E("ResolveSamplerDescriptor: no compatible sampled view for binding=%u ('%s') "
|
||||||
"textureId=%d imageFormat=%d numericDomain=%d",
|
"textureId=%d imageFormat=%d numericDomain=%d",
|
||||||
@@ -307,8 +322,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
static_cast<Int>(resource->format), static_cast<Int>(numericDomain));
|
static_cast<Int>(resource->format), static_cast<Int>(numericDomain));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// No reinterpretation requested: bind the depth-or-color aspect view the sync above
|
||||||
|
// already produced instead of re-entering GetOrCreateSampledImageView's sync path.
|
||||||
const VkImageView sampledImageView =
|
const VkImageView sampledImageView =
|
||||||
m_textureManager->GetOrCreateSampledImageView(*texture, sampledViewFormat);
|
sampledViewFormat == resource->format
|
||||||
|
? resource->sampledView
|
||||||
|
: m_textureManager->GetOrCreateSampledImageView(*texture, sampledViewFormat);
|
||||||
if (sampledImageView == VK_NULL_HANDLE) {
|
if (sampledImageView == VK_NULL_HANDLE) {
|
||||||
MGLOG_E("ResolveSamplerDescriptor: failed to resolve sampled view for binding=%u ('%s') "
|
MGLOG_E("ResolveSamplerDescriptor: failed to resolve sampled view for binding=%u ('%s') "
|
||||||
"textureId=%d imageFormat=%d viewFormat=%d numericDomain=%d",
|
"textureId=%d imageFormat=%d viewFormat=%d numericDomain=%d",
|
||||||
|
|||||||
@@ -176,6 +176,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Uint16 textureParamsVersion = 0;
|
Uint16 textureParamsVersion = 0;
|
||||||
Bool forceNearestFiltering = false;
|
Bool forceNearestFiltering = false;
|
||||||
Bool valid = false;
|
Bool valid = false;
|
||||||
|
// ResolveSampledImageViewFormat is pure in (image format, numeric domain), but a
|
||||||
|
// domain mismatch walks a ~184-entry format table. Memo the resolution per binding
|
||||||
|
// so a reinterpreted sampler pays that scan once, not once per draw.
|
||||||
|
VkFormat viewFormatSource = VK_FORMAT_UNDEFINED;
|
||||||
|
SamplerNumericDomain viewFormatDomain = SamplerNumericDomain::Unknown;
|
||||||
|
VkFormat viewFormat = VK_FORMAT_UNDEFINED;
|
||||||
|
Bool viewFormatValid = false;
|
||||||
};
|
};
|
||||||
mutable Vector<SamplerResolveMemo> m_samplerResolveMemo;
|
mutable Vector<SamplerResolveMemo> m_samplerResolveMemo;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1921,6 +1921,15 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
VkFormat VkTextureManager::ResolveSampledImageViewFormat(VkFormat imageFormat,
|
VkFormat VkTextureManager::ResolveSampledImageViewFormat(VkFormat imageFormat,
|
||||||
SamplerNumericDomain numericDomain) {
|
SamplerNumericDomain numericDomain) {
|
||||||
|
// Depth/stencil images always sample through the existing depth-aspect sampledView.
|
||||||
|
// Combined formats (D24S8, D32FS8) are multi-numeric, so vkuFormatIsSampledFloat is
|
||||||
|
// false for them by design, yet their depth aspect reads as float in every GL depth
|
||||||
|
// texture mode; Vulkan also forbids reinterpreting them through color-class views.
|
||||||
|
// Integer domains keep the same view (pre-reinterpretation behavior for stencil-index
|
||||||
|
// style access) rather than failing the draw.
|
||||||
|
if (vkuFormatIsDepthOrStencil(imageFormat)) {
|
||||||
|
return imageFormat;
|
||||||
|
}
|
||||||
if (imageFormat == VK_FORMAT_UNDEFINED || numericDomain == SamplerNumericDomain::Unknown ||
|
if (imageFormat == VK_FORMAT_UNDEFINED || numericDomain == SamplerNumericDomain::Unknown ||
|
||||||
FormatMatchesSamplerNumericDomain(imageFormat, numericDomain)) {
|
FormatMatchesSamplerNumericDomain(imageFormat, numericDomain)) {
|
||||||
return imageFormat;
|
return imageFormat;
|
||||||
|
|||||||
@@ -999,9 +999,27 @@ TEST(DirectVulkanSanity, SampledViewFormatMatchesSamplerNumericDomainWithoutChan
|
|||||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
||||||
VK_FORMAT_B10G11R11_UFLOAT_PACK32, SamplerNumericDomain::UnsignedInteger),
|
VK_FORMAT_B10G11R11_UFLOAT_PACK32, SamplerNumericDomain::UnsignedInteger),
|
||||||
VK_FORMAT_UNDEFINED);
|
VK_FORMAT_UNDEFINED);
|
||||||
|
|
||||||
|
// Depth/stencil formats never resolve through color-class reinterpretation; they pass
|
||||||
|
// through unchanged so the existing depth-aspect sampled view is used. Combined
|
||||||
|
// depth-stencil formats are multi-numeric (vkuFormatIsSampledFloat is false for them),
|
||||||
|
// so without the passthrough a plain sampler2D/sampler2DShadow on GL_DEPTH24_STENCIL8
|
||||||
|
// would resolve to UNDEFINED and the draw would be dropped.
|
||||||
|
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
||||||
|
VK_FORMAT_D24_UNORM_S8_UINT, SamplerNumericDomain::Float),
|
||||||
|
VK_FORMAT_D24_UNORM_S8_UINT);
|
||||||
|
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
||||||
|
VK_FORMAT_D32_SFLOAT_S8_UINT, SamplerNumericDomain::Float),
|
||||||
|
VK_FORMAT_D32_SFLOAT_S8_UINT);
|
||||||
|
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
||||||
|
VK_FORMAT_D32_SFLOAT, SamplerNumericDomain::Float),
|
||||||
|
VK_FORMAT_D32_SFLOAT);
|
||||||
|
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
||||||
|
VK_FORMAT_D24_UNORM_S8_UINT, SamplerNumericDomain::UnsignedInteger),
|
||||||
|
VK_FORMAT_D24_UNORM_S8_UINT);
|
||||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewFormat(
|
||||||
VK_FORMAT_D32_SFLOAT, SamplerNumericDomain::UnsignedInteger),
|
VK_FORMAT_D32_SFLOAT, SamplerNumericDomain::UnsignedInteger),
|
||||||
VK_FORMAT_UNDEFINED);
|
VK_FORMAT_D32_SFLOAT);
|
||||||
|
|
||||||
EXPECT_TRUE(VkTextureManager::AreSampledImageViewFormatsCompatible(
|
EXPECT_TRUE(VkTextureManager::AreSampledImageViewFormatsCompatible(
|
||||||
VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_UINT));
|
VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_UINT));
|
||||||
|
|||||||
Reference in New Issue
Block a user