Ands new depth stencil format to support all combinations on Vulkan.

Tested By: hyperion, nwtour
Differential Revision: https://code.wildfiregames.com/D4878
This was SVN commit r27421.
This commit is contained in:
Vladislav Belov 2023-01-12 06:32:52 +00:00
parent b573993000
commit ccda54a662
15 changed files with 121 additions and 89 deletions

View File

@ -96,10 +96,14 @@ CPostprocManager::~CPostprocManager()
bool CPostprocManager::IsEnabled() const
{
Renderer::Backend::IDevice* device = g_VideoMode.GetBackendDevice();
const bool isDepthStencilFormatPresent =
device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, true, true)
!= Renderer::Backend::Format::UNDEFINED;
return
g_RenderingOptions.GetPostProc() &&
device->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
device->IsTextureFormatSupported(Renderer::Backend::Format::D24_S8);
isDepthStencilFormatPresent;
}
void CPostprocManager::Cleanup()
@ -224,7 +228,11 @@ void CPostprocManager::RecreateBuffers()
m_DepthTex = backendDevice->CreateTexture2D("PostProcDepthTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
Renderer::Backend::Format::D24_S8, m_Width, m_Height,
backendDevice->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
true, true),
m_Width, m_Height,
Renderer::Backend::Sampler::MakeDefaultSampler(
Renderer::Backend::Sampler::Filter::LINEAR,
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
@ -629,7 +637,11 @@ void CPostprocManager::CreateMultisampleBuffer()
Renderer::Backend::ITexture::Type::TEXTURE_2D_MULTISAMPLE,
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT |
Renderer::Backend::ITexture::Usage::TRANSFER_SRC,
Renderer::Backend::Format::D24_S8, m_Width, m_Height,
backendDevice->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT |
Renderer::Backend::ITexture::Usage::TRANSFER_SRC,
true, true),
m_Width, m_Height,
Renderer::Backend::Sampler::MakeDefaultSampler(
Renderer::Backend::Sampler::Filter::LINEAR,
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, m_MultisampleCount);

View File

@ -519,14 +519,14 @@ void ShadowMapInternals::CreateTexture()
const char* formatName;
Renderer::Backend::Format backendFormat = Renderer::Backend::Format::UNDEFINED;
#if CONFIG2_GLES
formatName = "Format::D24";
backendFormat = Renderer::Backend::Format::D24;
formatName = "Format::D24_UNORM";
backendFormat = Renderer::Backend::Format::D24_UNORM;
#else
switch (DepthTextureBits)
{
case 16: formatName = "Format::D16"; backendFormat = Renderer::Backend::Format::D16; break;
case 24: formatName = "Format::D24"; backendFormat = Renderer::Backend::Format::D24; break;
case 32: formatName = "Format::D32"; backendFormat = Renderer::Backend::Format::D32; break;
case 16: formatName = "Format::D16_UNORM"; backendFormat = Renderer::Backend::Format::D16_UNORM; break;
case 24: formatName = "Format::D24_UNORM"; backendFormat = Renderer::Backend::Format::D24_UNORM; break;
case 32: formatName = "Format::D32_SFLOAT"; backendFormat = Renderer::Backend::Format::D32_SFLOAT; break;
default:
formatName = "Default";
backendFormat = backendDevice->GetPreferredDepthStencilFormat(

View File

@ -51,10 +51,11 @@ enum class Format
R32G32B32_SFLOAT,
R32G32B32A32_SFLOAT,
D16,
D24,
D24_S8,
D32,
D16_UNORM,
D24_UNORM,
D24_UNORM_S8_UINT,
D32_SFLOAT,
D32_SFLOAT_S8_UINT,
BC1_RGB_UNORM,
BC1_RGBA_UNORM,
@ -65,10 +66,11 @@ enum class Format
inline bool IsDepthFormat(const Format format)
{
return
format == Format::D16 ||
format == Format::D24 ||
format == Format::D24_S8 ||
format == Format::D32;
format == Format::D16_UNORM ||
format == Format::D24_UNORM ||
format == Format::D24_UNORM_S8_UINT ||
format == Format::D32_SFLOAT ||
format == Format::D32_SFLOAT_S8_UINT;
}
} // namespace Backend

View File

@ -156,7 +156,7 @@ bool CDevice::IsFramebufferFormatSupported(const Format UNUSED(format)) const
Format CDevice::GetPreferredDepthStencilFormat(
const uint32_t, const bool, const bool) const
{
return Format::D24_S8;
return Format::D24_UNORM_S8_UINT;
}
std::unique_ptr<IDevice> CreateDevice(SDL_Window* UNUSED(window))

View File

@ -1010,17 +1010,20 @@ bool CDevice::IsTextureFormatSupported(const Format format) const
case Format::R32G32B32A32_SFLOAT:
break;
case Format::D16: FALLTHROUGH;
case Format::D24: FALLTHROUGH;
case Format::D32:
case Format::D16_UNORM: FALLTHROUGH;
case Format::D24_UNORM: FALLTHROUGH;
case Format::D32_SFLOAT:
supported = true;
break;
case Format::D24_S8:
case Format::D24_UNORM_S8_UINT:
#if !CONFIG2_GLES
supported = true;
#endif
break;
case Format::D32_SFLOAT_S8_UINT:
break;
case Format::BC1_RGB_UNORM: FALLTHROUGH;
case Format::BC1_RGBA_UNORM: FALLTHROUGH;
case Format::BC2_UNORM: FALLTHROUGH;
@ -1063,10 +1066,10 @@ Format CDevice::GetPreferredDepthStencilFormat(
#if CONFIG2_GLES
return Format::UNDEFINED;
#else
return Format::D24_S8;
return Format::D24_UNORM_S8_UINT;
#endif
else
return Format::D24;
return Format::D24_UNORM;
}
std::unique_ptr<IDevice> CreateDevice(SDL_Window* window, const bool arb)

View File

@ -111,15 +111,6 @@ GLenum BufferTypeToGLTarget(const CBuffer::Type type)
return target;
}
#if !CONFIG2_GLES
bool IsDepthTexture(const Format format)
{
return
format == Format::D16 || format == Format::D24 ||
format == Format::D32 || format == Format::D24_S8;
}
#endif // !CONFIG2_GLES
void UploadDynamicBufferRegionImpl(
const GLenum target, const uint32_t bufferSize,
const uint32_t dataOffset, const uint32_t dataSize,
@ -1211,7 +1202,7 @@ void CDeviceCommandContext::SetTexture(const int32_t bindingSlot, ITexture* text
#if !CONFIG2_GLES
if (textureUnit.type == GL_SAMPLER_2D_SHADOW)
{
if (!IsDepthTexture(texture->GetFormat()))
if (!IsDepthFormat(texture->GetFormat()))
{
LOGERROR("CDeviceCommandContext::SetTexture: Invalid texture type (expected depth texture)");
return;

View File

@ -90,7 +90,10 @@ std::unique_ptr<CFramebuffer> CFramebuffer::Create(
framebuffer->m_Width = depthStencilAttachmentTexture->GetWidth();
framebuffer->m_Height = depthStencilAttachmentTexture->GetHeight();
framebuffer->m_AttachmentMask |= GL_DEPTH_BUFFER_BIT;
if (depthStencilAttachmentTexture->GetFormat() == Format::D24_S8)
const bool hasStencil =
depthStencilAttachmentTexture->GetFormat() == Format::D24_UNORM_S8_UINT ||
depthStencilAttachmentTexture->GetFormat() == Format::D32_SFLOAT_S8_UINT;
if (hasStencil)
framebuffer->m_AttachmentMask |= GL_STENCIL_BUFFER_BIT;
if (colorAttachment)
{
@ -98,18 +101,14 @@ std::unique_ptr<CFramebuffer> CFramebuffer::Create(
ENSURE(colorAttachment->texture->GetHeight() == depthStencilAttachmentTexture->GetHeight());
ENSURE(colorAttachment->texture->GetType() == depthStencilAttachmentTexture->GetType());
}
ENSURE(
depthStencilAttachmentTexture->GetFormat() == Format::D16 ||
depthStencilAttachmentTexture->GetFormat() == Format::D24 ||
depthStencilAttachmentTexture->GetFormat() == Format::D32 ||
depthStencilAttachmentTexture->GetFormat() == Format::D24_S8);
ENSURE(IsDepthFormat(depthStencilAttachmentTexture->GetFormat()));
#if CONFIG2_GLES
ENSURE(depthStencilAttachmentTexture->GetFormat() != Format::D24_S8);
ENSURE(depthStencilAttachmentTexture->GetFormat() == Format::D24_UNORM);
const GLenum attachment = GL_DEPTH_ATTACHMENT;
ENSURE(depthStencilAttachmentTexture->GetType() == CTexture::Type::TEXTURE_2D);
const GLenum textureTarget = GL_TEXTURE_2D;
#else
const GLenum attachment = depthStencilAttachmentTexture->GetFormat() == Format::D24_S8 ?
const GLenum attachment = hasStencil ?
GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
const GLenum textureTarget = depthStencilAttachmentTexture->GetType() == CTexture::Type::TEXTURE_2D_MULTISAMPLE ?
GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;

View File

@ -211,33 +211,33 @@ std::unique_ptr<CTexture> CTexture::Create(
break;
#if CONFIG2_GLES
// GLES requires pixel type == UNSIGNED_SHORT or UNSIGNED_INT for depth.
case Format::D16: FALLTHROUGH;
case Format::D24: FALLTHROUGH;
case Format::D32:
case Format::D16_UNORM: FALLTHROUGH;
case Format::D24_UNORM: FALLTHROUGH;
case Format::D32_SFLOAT:
internalFormat = GL_DEPTH_COMPONENT;
pixelFormat = GL_DEPTH_COMPONENT;
pixelType = GL_UNSIGNED_SHORT;
break;
case Format::D24_S8:
case Format::D24_UNORM_S8_UINT:
debug_warn("Unsupported format");
break;
#else
case Format::D16:
case Format::D16_UNORM:
internalFormat = GL_DEPTH_COMPONENT16;
pixelFormat = GL_DEPTH_COMPONENT;
pixelType = GL_UNSIGNED_SHORT;
break;
case Format::D24:
case Format::D24_UNORM:
internalFormat = GL_DEPTH_COMPONENT24;
pixelFormat = GL_DEPTH_COMPONENT;
pixelType = GL_UNSIGNED_SHORT;
break;
case Format::D32:
case Format::D32_SFLOAT:
internalFormat = GL_DEPTH_COMPONENT32;
pixelFormat = GL_DEPTH_COMPONENT;
pixelType = GL_UNSIGNED_SHORT;
break;
case Format::D24_S8:
case Format::D24_UNORM_S8_UINT:
internalFormat = GL_DEPTH24_STENCIL8_EXT;
pixelFormat = GL_DEPTH_STENCIL_EXT;
pixelType = GL_UNSIGNED_INT_24_8_EXT;
@ -271,7 +271,7 @@ std::unique_ptr<CTexture> CTexture::Create(
{
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_RGBA8, width, height, GL_TRUE);
}
else if (format == Format::D24_S8)
else if (format == Format::D24_UNORM_S8_UINT)
{
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_DEPTH24_STENCIL8_EXT, width, height, GL_TRUE);
}
@ -284,8 +284,7 @@ std::unique_ptr<CTexture> CTexture::Create(
#if !CONFIG2_GLES
if (format == Format::D16 || format == Format::D24 || format == Format::D32 ||
format == Format::D24_S8)
if (IsDepthFormat(format))
{
if (defaultSamplerDesc.compareEnabled)
{

View File

@ -285,10 +285,7 @@ uint32_t CDescriptorManager::GetTextureDescriptor(CTexture* texture)
uint32_t binding = 0;
if (texture->GetType() == ITexture::Type::TEXTURE_2D &&
(texture->GetFormat() == Format::D16 ||
texture->GetFormat() == Format::D24 ||
texture->GetFormat() == Format::D32 ||
texture->GetFormat() == Format::D24_S8) &&
IsDepthFormat(texture->GetFormat()) &&
texture->IsCompareEnabled())
binding = 2;
else if (texture->GetType() == ITexture::Type::TEXTURE_CUBE)

View File

@ -784,38 +784,25 @@ void CDevice::OnWindowResize(const uint32_t width, const uint32_t height)
bool CDevice::IsTextureFormatSupported(const Format format) const
{
bool supported = false;
switch (format)
{
case Format::UNDEFINED:
break;
case Format::R8G8B8_UNORM: FALLTHROUGH;
case Format::R8G8B8A8_UNORM: FALLTHROUGH;
case Format::A8_UNORM: FALLTHROUGH;
case Format::L8_UNORM: FALLTHROUGH;
case Format::R32_SFLOAT: FALLTHROUGH;
case Format::R32G32_SFLOAT: FALLTHROUGH;
case Format::R32G32B32_SFLOAT: FALLTHROUGH;
case Format::R32G32B32A32_SFLOAT: FALLTHROUGH;
case Format::D16: FALLTHROUGH;
case Format::D24: FALLTHROUGH;
case Format::D24_S8: FALLTHROUGH;
case Format::D32:
supported = true;
break;
return false;
case Format::BC1_RGB_UNORM: FALLTHROUGH;
case Format::BC1_RGBA_UNORM: FALLTHROUGH;
case Format::BC2_UNORM: FALLTHROUGH;
case Format::BC3_UNORM:
supported = m_Capabilities.S3TC;
break;
return m_Capabilities.S3TC;
default:
break;
}
return supported;
VkFormatProperties formatProperties{};
vkGetPhysicalDeviceFormatProperties(
m_ChoosenDevice.device, Mapping::FromFormat(format), &formatProperties);
return formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
}
bool CDevice::IsFramebufferFormatSupported(const Format format) const
@ -829,28 +816,58 @@ bool CDevice::IsFramebufferFormatSupported(const Format format) const
}
Format CDevice::GetPreferredDepthStencilFormat(
const uint32_t UNUSED(usage), const bool depth, const bool stencil) const
const uint32_t usage, const bool depth, const bool stencil) const
{
// TODO: account usage.
ENSURE(depth || stencil);
Format format = Format::UNDEFINED;
if (stencil)
{
format = Format::D24_S8;
// https://github.com/KhronosGroup/Vulkan-Guide/blob/main/chapters/depth.adoc#depth-formats
// At least one of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT
// must also be supported.
if (IsFormatSupportedForUsage(Format::D24_UNORM_S8_UINT, usage))
format = Format::D24_UNORM_S8_UINT;
else
format = Format::D32_SFLOAT_S8_UINT;
}
else
{
std::array<Format, 3> formatRequestOrder;
// TODO: add most known vendors to enum.
// https://developer.nvidia.com/blog/vulkan-dos-donts/
if (m_ChoosenDevice.properties.vendorID == 0x10DE)
format = Format::D24;
formatRequestOrder = {Format::D24_UNORM, Format::D32_SFLOAT, Format::D16_UNORM};
else
format = Format::D24;
formatRequestOrder = {Format::D32_SFLOAT, Format::D24_UNORM, Format::D16_UNORM};
for (const Format formatRequest : formatRequestOrder)
if (IsFormatSupportedForUsage(formatRequest, usage))
{
format = formatRequest;
break;
}
}
ENSURE(IsFramebufferFormatSupported(format));
return format;
}
bool CDevice::IsFormatSupportedForUsage(const Format format, const uint32_t usage) const
{
VkFormatProperties formatProperties{};
vkGetPhysicalDeviceFormatProperties(
m_ChoosenDevice.device, Mapping::FromFormat(format), &formatProperties);
VkFormatFeatureFlags expectedFeatures = 0;
if (usage & ITexture::Usage::COLOR_ATTACHMENT)
expectedFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
if (usage & ITexture::Usage::DEPTH_STENCIL_ATTACHMENT)
expectedFeatures |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
if (usage & ITexture::Usage::SAMPLED)
expectedFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
if (usage & ITexture::Usage::TRANSFER_SRC)
expectedFeatures |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
if (usage & ITexture::Usage::TRANSFER_DST)
expectedFeatures |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
return (formatProperties.optimalTilingFeatures & expectedFeatures) == expectedFeatures;
}
void CDevice::ScheduleObjectToDestroy(
VkObjectType type, const uint64_t handle, const VmaAllocation allocation)
{

View File

@ -167,6 +167,8 @@ private:
void ProcessObjectToDestroyQueue(const bool ignoreFrameID = false);
void ProcessTextureToDestroyQueue(const bool ignoreFrameID = false);
bool IsFormatSupportedForUsage(const Format format, const uint32_t usage) const;
std::string m_Name;
std::string m_Version;
std::string m_VendorID;

View File

@ -370,7 +370,12 @@ void CDeviceCommandContext::ClearFramebuffer(const bool color, const bool depth,
{
ENSURE(m_Framebuffer->GetDepthStencilAttachment());
if (stencil)
ENSURE(m_Framebuffer->GetDepthStencilAttachment()->GetFormat() == Format::D24_S8);
{
const Format depthStencilFormat =
m_Framebuffer->GetDepthStencilAttachment()->GetFormat();
ENSURE(depthStencilFormat == Format::D24_UNORM_S8_UINT ||
depthStencilFormat == Format::D32_SFLOAT_S8_UINT);
}
VkClearAttachment clearAttachment{};
if (depth)
clearAttachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;

View File

@ -183,10 +183,11 @@ VkFormat FromFormat(const Format format)
CASE(R32G32B32_SFLOAT)
CASE(R32G32B32A32_SFLOAT)
CASE2(D16, D16_UNORM)
CASE2(D24, X8_D24_UNORM_PACK32)
CASE2(D24_S8, D24_UNORM_S8_UINT)
CASE2(D32, D32_SFLOAT)
CASE(D16_UNORM)
CASE2(D24_UNORM, X8_D24_UNORM_PACK32)
CASE(D24_UNORM_S8_UINT)
CASE(D32_SFLOAT_S8_UINT)
CASE(D32_SFLOAT)
CASE2(BC1_RGB_UNORM, BC1_RGB_UNORM_BLOCK)
CASE2(BC1_RGBA_UNORM, BC1_RGBA_UNORM_BLOCK)

View File

@ -186,7 +186,10 @@ std::unique_ptr<CSwapChain> CSwapChain::Create(
swapChain->m_DepthTexture = CTexture::Create(
device, "SwapChainDepthTexture", ITexture::Type::TEXTURE_2D,
ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, Format::D24_S8,
ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
true, true),
swapChainWidth, swapChainHeight, Sampler::MakeDefaultSampler(
Sampler::Filter::NEAREST, Sampler::AddressMode::CLAMP_TO_EDGE),
1, 1);

View File

@ -76,6 +76,7 @@ std::unique_ptr<CTexture> CTexture::Create(
VkImageUsageFlags usageFlags = 0;
// Vulkan 1.0 implies that TRANSFER_SRC and TRANSFER_DST are supported.
// TODO: account Vulkan 1.1.
if (usage & Usage::TRANSFER_SRC)
usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
if (usage & Usage::TRANSFER_DST)
@ -115,7 +116,7 @@ std::unique_ptr<CTexture> CTexture::Create(
{
texture->m_AttachmentImageAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
texture->m_SamplerImageAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
if (format == Format::D24_S8)
if (format == Format::D24_UNORM_S8_UINT || format == Format::D32_SFLOAT_S8_UINT)
texture->m_AttachmentImageAspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
else