From b9588a800bda713d993736ab3c359a9d58e9aaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Fri, 26 Jun 2020 11:47:46 +0200 Subject: rhi: add support for D24 / D24S8 formats Change-Id: I7ba14d30fa57bcb92cd764aed6c85cde853935b4 Reviewed-by: Laszlo Agocs --- src/gui/rhi/qrhi.cpp | 6 ++++++ src/gui/rhi/qrhi_p.h | 2 ++ src/gui/rhi/qrhid3d11.cpp | 14 ++++++++++++++ src/gui/rhi/qrhigles2.cpp | 18 ++++++++++++++++++ src/gui/rhi/qrhimetal.mm | 17 +++++++++++++---- src/gui/rhi/qrhivulkan.cpp | 27 ++++++++++++++++++--------- 6 files changed, 71 insertions(+), 13 deletions(-) (limited to 'src/gui') diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 6e7c975753..1ad275e768 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -2245,6 +2245,10 @@ QRhiResource::Type QRhiRenderBuffer::resourceType() const \value D16 16-bit depth (normalized unsigned integer) + \value D24 24-bit depth (normalized unsigned integer) + + \value D24S8 24-bit depth (normalized unsigned integer), 8 bit stencil + \value D32F 32-bit depth (32-bit float) \value BC1 @@ -4137,6 +4141,8 @@ void QRhiImplementation::textureFormatInfo(QRhiTexture::Format format, const QSi case QRhiTexture::D16: bpc = 2; break; + case QRhiTexture::D24: + case QRhiTexture::D24S8: case QRhiTexture::D32F: bpc = 4; break; diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index c46aeb3618..cfd770d41b 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -753,6 +753,8 @@ public: R32F, D16, + D24, + D24S8, D32F, BC1, diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index e5b03e1d0e..7015ca664e 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -1204,6 +1204,10 @@ static inline DXGI_FORMAT toD3DTextureFormat(QRhiTexture::Format format, QRhiTex case QRhiTexture::D16: return DXGI_FORMAT_R16_TYPELESS; + case QRhiTexture::D24: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case QRhiTexture::D24S8: + return DXGI_FORMAT_D24_UNORM_S8_UINT; case QRhiTexture::D32F: return DXGI_FORMAT_R32_TYPELESS; @@ -1283,6 +1287,8 @@ static inline bool isDepthTextureFormat(QRhiTexture::Format format) { switch (format) { case QRhiTexture::Format::D16: + case QRhiTexture::Format::D24: + case QRhiTexture::Format::D24S8: case QRhiTexture::Format::D32F: return true; @@ -2839,6 +2845,10 @@ static inline DXGI_FORMAT toD3DDepthTextureSRVFormat(QRhiTexture::Format format) switch (format) { case QRhiTexture::Format::D16: return DXGI_FORMAT_R16_FLOAT; + case QRhiTexture::Format::D24: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case QRhiTexture::Format::D24S8: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; case QRhiTexture::Format::D32F: return DXGI_FORMAT_R32_FLOAT; default: @@ -2852,6 +2862,10 @@ static inline DXGI_FORMAT toD3DDepthTextureDSVFormat(QRhiTexture::Format format) switch (format) { case QRhiTexture::Format::D16: return DXGI_FORMAT_D16_UNORM; + case QRhiTexture::Format::D24: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case QRhiTexture::Format::D24S8: + return DXGI_FORMAT_D24_UNORM_S8_UINT; case QRhiTexture::Format::D32F: return DXGI_FORMAT_D32_FLOAT; default: diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 9196a88199..db131c12b0 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -775,6 +775,18 @@ static inline void toGlTextureFormat(QRhiTexture::Format format, const QRhiGles2 *glformat = GL_DEPTH_COMPONENT; *gltype = GL_UNSIGNED_SHORT; break; + case QRhiTexture::D24: + *glintformat = GL_DEPTH_COMPONENT24; + *glsizedintformat = *glintformat; + *glformat = GL_DEPTH_COMPONENT; + *gltype = GL_UNSIGNED_SHORT; + break; + case QRhiTexture::D24S8: + *glintformat = GL_DEPTH24_STENCIL8; + *glsizedintformat = *glintformat; + *glformat = GL_DEPTH_STENCIL; + *gltype = GL_UNSIGNED_SHORT; + break; case QRhiTexture::D32F: *glintformat = GL_DEPTH_COMPONENT32F; *glsizedintformat = *glintformat; @@ -801,6 +813,12 @@ bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture case QRhiTexture::D32F: return caps.depthTexture; + case QRhiTexture::D24: + return caps.depth24; + + case QRhiTexture::D24S8: + return caps.depth24 && caps.packedDepthStencil; + case QRhiTexture::BGRA8: return caps.bgraExternalFormat; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 6998c55bf9..ee7735c1bb 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -2235,7 +2235,7 @@ QRhiBuffer::NativeBuffer QMetalBuffer::nativeBuffer() return { { &d->buf[0] }, 1 }; } -static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags) +static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags, const QRhiMetalData *d) { const bool srgb = flags.testFlag(QRhiTexture::sRGB); switch (format) { @@ -2269,11 +2269,20 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR case QRhiTexture::R32F: return MTLPixelFormatR32Float; - case QRhiTexture::D16: #ifdef Q_OS_MACOS + case QRhiTexture::D16: return MTLPixelFormatDepth16Unorm; + case QRhiTexture::D24: + return [d->dev isDepth24Stencil8PixelFormatSupported] ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float; + case QRhiTexture::D24S8: + return [d->dev isDepth24Stencil8PixelFormatSupported] ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; #else + case QRhiTexture::D16: + return MTLPixelFormatDepth32Float; + case QRhiTexture::D24: return MTLPixelFormatDepth32Float; + case QRhiTexture::D24S8: + return MTLPixelFormatDepth32Float_Stencil8; #endif case QRhiTexture::D32F: return MTLPixelFormatDepth32Float; @@ -2443,7 +2452,7 @@ bool QMetalRenderBuffer::create() case Color: desc.storageMode = MTLStorageModePrivate; if (m_backingFormatHint != QRhiTexture::UnknownFormat) - d->format = toMetalTextureFormat(m_backingFormatHint, {}); + d->format = toMetalTextureFormat(m_backingFormatHint, {}, rhiD->d); else d->format = MTLPixelFormatRGBA8Unorm; desc.pixelFormat = d->format; @@ -2533,7 +2542,7 @@ bool QMetalTexture::prepareCreate(QSize *adjustedSize) const bool hasMipMaps = m_flags.testFlag(MipMapped); QRHI_RES_RHI(QRhiMetal); - d->format = toMetalTextureFormat(m_format, m_flags); + d->format = toMetalTextureFormat(m_format, m_flags, rhiD->d); mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1; samples = rhiD->effectiveSampleCount(m_sampleCount); if (samples > 1) { diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 919f4f039f..ee75b0eb37 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -834,6 +834,10 @@ static inline VkFormat toVkTextureFormat(QRhiTexture::Format format, QRhiTexture case QRhiTexture::D16: return VK_FORMAT_D16_UNORM; + case QRhiTexture::D24: + return VK_FORMAT_X8_D24_UNORM_PACK32; + case QRhiTexture::D24S8: + return VK_FORMAT_D24_UNORM_S8_UINT; case QRhiTexture::D32F: return VK_FORMAT_D32_SFLOAT; @@ -930,10 +934,12 @@ static inline QRhiTexture::Format colorTextureFormatFromVkFormat(VkFormat format return QRhiTexture::UnknownFormat; } -static inline bool isDepthTextureFormat(QRhiTexture::Format format) +static constexpr inline bool isDepthTextureFormat(QRhiTexture::Format format) { switch (format) { case QRhiTexture::Format::D16: + case QRhiTexture::Format::D24: + case QRhiTexture::Format::D24S8: case QRhiTexture::Format::D32F: return true; @@ -942,6 +948,11 @@ static inline bool isDepthTextureFormat(QRhiTexture::Format format) } } +static constexpr inline VkImageAspectFlags aspectMaskForTextureFormat(QRhiTexture::Format format) +{ + return isDepthTextureFormat(format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; +} + // Transient images ("render buffers") backed by lazily allocated memory are // managed manually without going through vk_mem_alloc since it does not offer // any support for such images. This should be ok since in practice there @@ -2723,8 +2734,7 @@ void QRhiVulkan::trackedImageBarrier(QVkCommandBuffer *cbD, QVkTexture *texD, VkImageMemoryBarrier barrier; memset(&barrier, 0, sizeof(barrier)); barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.subresourceRange.aspectMask = !isDepthTextureFormat(texD->m_format) - ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; + barrier.subresourceRange.aspectMask = aspectMaskForTextureFormat(texD->m_format); barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; barrier.subresourceRange.baseArrayLayer = 0; @@ -3933,8 +3943,7 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi VkImageMemoryBarrier barrier; memset(&barrier, 0, sizeof(barrier)); barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.subresourceRange.aspectMask = !isDepthTextureFormat(texD->m_format) - ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; + barrier.subresourceRange.aspectMask = aspectMaskForTextureFormat(texD->m_format); barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; barrier.subresourceRange.baseArrayLayer = 0; @@ -5521,7 +5530,7 @@ bool QVkTexture::finishCreate() { QRHI_RES_RHI(QRhiVulkan); - const bool isDepth = isDepthTextureFormat(m_format); + const auto aspectMask = aspectMaskForTextureFormat(m_format); const bool isCube = m_flags.testFlag(CubeMap); VkImageViewCreateInfo viewInfo; @@ -5534,7 +5543,7 @@ bool QVkTexture::finishCreate() viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; - viewInfo.subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + viewInfo.subresourceRange.aspectMask = aspectMask; viewInfo.subresourceRange.levelCount = mipLevelCount; viewInfo.subresourceRange.layerCount = isCube ? 6 : 1; @@ -5656,7 +5665,7 @@ VkImageView QVkTexture::imageViewForLevel(int level) if (perLevelImageViews[level] != VK_NULL_HANDLE) return perLevelImageViews[level]; - const bool isDepth = isDepthTextureFormat(m_format); + const VkImageAspectFlags aspectMask = aspectMaskForTextureFormat(m_format); const bool isCube = m_flags.testFlag(CubeMap); VkImageViewCreateInfo viewInfo; @@ -5669,7 +5678,7 @@ VkImageView QVkTexture::imageViewForLevel(int level) viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; - viewInfo.subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + viewInfo.subresourceRange.aspectMask = aspectMask; viewInfo.subresourceRange.baseMipLevel = uint32_t(level); viewInfo.subresourceRange.levelCount = 1; viewInfo.subresourceRange.baseArrayLayer = 0; -- cgit v1.2.3