Commit 3b2ce2d3 authored by Laszlo Agocs's avatar Laszlo Agocs

vk: Add some compressed texture plumbing

parent eeb7d0c2
......@@ -155,7 +155,7 @@ static QByteArrayList loadBC1(const QString &filename, QSize *size)
void Window::customInit()
{
if (!m_r->canTextureFormatBeSupported(QRhiTexture::BC1))
if (!m_r->isTextureFormatSupported(QRhiTexture::BC1))
qFatal("This backend does not support BC1");
d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(cube));
......
......@@ -350,9 +350,9 @@ QMatrix4x4 QRhi::clipSpaceCorrMatrix() const
return d->clipSpaceCorrMatrix();
}
bool QRhi::canTextureFormatBeSupported(QRhiTexture::Format format) const
bool QRhi::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
return d->canTextureFormatBeSupported(format);
return d->isTextureFormatSupported(format, flags);
}
QRhiGraphicsPipeline *QRhi::newGraphicsPipeline()
......
......@@ -261,6 +261,7 @@ struct Q_RHI_EXPORT QRhiTextureUploadDescription
struct Q_RHI_EXPORT Layer {
struct Q_RHI_EXPORT MipLevel {
MipLevel() { }
// either a QImage or compressed data (not both)
MipLevel(const QImage &image_) : image(image_) { }
MipLevel(const QByteArray &compressedData_) : compressedData(compressedData_) { }
QImage image;
......@@ -949,10 +950,10 @@ public:
QRhiTextureRenderTarget::Flags flags = QRhiTextureRenderTarget::Flags());
/*
Render to a QWindow (must be Vulkan/Metal/OpenGLSurface as appropriate):
Rendering to a QWindow (must be Vulkan/Metal/OpenGLSurface as appropriate):
Create a swapchain.
Call build() on the swapchain whenever the size is different than before.
Call release() on QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed.
Call buildOrResize() on the swapchain whenever the size is different than before.
Call release() on the swapchain on QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed.
Then on every frame:
beginFrame(sc);
updates = nextResourceUpdateBatch();
......@@ -961,8 +962,6 @@ public:
...
endPass(sc->currentFrameCommandBuffer());
endFrame(sc); // this queues the Present, begin/endFrame manages double buffering internally
Also works with a QVulkanWindow from startNextFrame(). Use the overload of build() in initSwapChainResources().
*/
QRhiSwapChain *newSwapChain();
FrameOpResult beginFrame(QRhiSwapChain *swapChain);
......@@ -977,8 +976,8 @@ public:
void beginPass(QRhiRenderTarget *rt,
QRhiCommandBuffer *cb,
const QRhiColorClearValue &colorClearValue,
const QRhiDepthStencilClearValue &depthStencilClearValue,
const QRhiColorClearValue &colorClearValue, // ignored when rt has PreserveColorContents
const QRhiDepthStencilClearValue &depthStencilClearValue, // ignored when no ds attachment
QRhiResourceUpdateBatch *resourceUpdates = nullptr);
void endPass(QRhiCommandBuffer *cb);
......@@ -1031,10 +1030,7 @@ public:
// instead of just mvp, to their vertex shaders)
QMatrix4x4 clipSpaceCorrMatrix() const;
// This is not isTextureFormatSupported: the result does not guarantee
// runtime availability, it only helps determining the guaranteed hopeless
// cases based on a static list from the backends.
bool canTextureFormatBeSupported(QRhiTexture::Format format) const;
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = QRhiTexture::Flags()) const;
protected:
QRhi();
......
......@@ -115,7 +115,7 @@ public:
virtual int ubufAlignment() const = 0;
virtual bool isYUpInFramebuffer() const = 0;
virtual QMatrix4x4 clipSpaceCorrMatrix() const = 0;
virtual bool canTextureFormatBeSupported(QRhiTexture::Format format) const = 0;
virtual bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const = 0;
QVector<QRhiResourceUpdateBatch *> resUpdPool;
QBitArray resUpdPoolMap;
......
......@@ -228,8 +228,10 @@ QMatrix4x4 QRhiD3D11::clipSpaceCorrMatrix() const
return m;
}
bool QRhiD3D11::canTextureFormatBeSupported(QRhiTexture::Format format) const
bool QRhiD3D11::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
Q_UNUSED(flags);
if (format >= QRhiTexture::ETC2_RGB8 && format <= QRhiTexture::ASTC_12x12)
return false;
......
......@@ -407,7 +407,7 @@ public:
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
QMatrix4x4 clipSpaceCorrMatrix() const override;
bool canTextureFormatBeSupported(QRhiTexture::Format format) const override;
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
void create();
void destroy();
......
......@@ -178,8 +178,10 @@ QMatrix4x4 QRhiGles2::clipSpaceCorrMatrix() const
return QMatrix4x4(); // identity
}
bool QRhiGles2::canTextureFormatBeSupported(QRhiTexture::Format format) const
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
Q_UNUSED(flags);
if (format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7)
return false;
......
......@@ -365,7 +365,7 @@ public:
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
QMatrix4x4 clipSpaceCorrMatrix() const override;
bool canTextureFormatBeSupported(QRhiTexture::Format format) const override;
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
void ensureContext(QSurface *surface = nullptr);
void create();
......
......@@ -254,8 +254,10 @@ QMatrix4x4 QRhiMetal::clipSpaceCorrMatrix() const
return QMatrix4x4(); // identity
}
bool QRhiMetal::canTextureFormatBeSupported(QRhiTexture::Format format) const
bool QRhiMetal::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
Q_UNUSED(flags);
if (format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7)
return false;
......
......@@ -296,7 +296,7 @@ public:
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
QMatrix4x4 clipSpaceCorrMatrix() const override;
bool canTextureFormatBeSupported(QRhiTexture::Format format) const override;
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
void create();
void destroy();
......
......@@ -439,6 +439,57 @@ static inline VkFormat toVkTextureFormat(QRhiTexture::Format format, QRhiTexture
case QRhiTexture::D32:
return VK_FORMAT_D32_SFLOAT;
case QRhiTexture::BC1:
return srgb ? VK_FORMAT_BC1_RGB_SRGB_BLOCK : VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case QRhiTexture::BC2:
return srgb ? VK_FORMAT_BC2_SRGB_BLOCK : VK_FORMAT_BC2_UNORM_BLOCK;
case QRhiTexture::BC3:
return srgb ? VK_FORMAT_BC3_SRGB_BLOCK : VK_FORMAT_BC3_UNORM_BLOCK;
case QRhiTexture::BC4:
return VK_FORMAT_BC4_UNORM_BLOCK;
case QRhiTexture::BC5:
return VK_FORMAT_BC5_UNORM_BLOCK;
case QRhiTexture::BC6H:
return VK_FORMAT_BC6H_UFLOAT_BLOCK;
case QRhiTexture::BC7:
return srgb ? VK_FORMAT_BC7_SRGB_BLOCK : VK_FORMAT_BC7_UNORM_BLOCK;
case QRhiTexture::ETC2_RGB8:
return srgb ? VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
case QRhiTexture::ETC2_RGB8A1:
return srgb ? VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
case QRhiTexture::ETC2_RGBA8:
return srgb ? VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
case QRhiTexture::ASTC_4x4:
return srgb ? VK_FORMAT_ASTC_4x4_SRGB_BLOCK : VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
case QRhiTexture::ASTC_5x4:
return srgb ? VK_FORMAT_ASTC_5x4_SRGB_BLOCK : VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
case QRhiTexture::ASTC_5x5:
return srgb ? VK_FORMAT_ASTC_5x5_SRGB_BLOCK : VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
case QRhiTexture::ASTC_6x5:
return srgb ? VK_FORMAT_ASTC_6x5_SRGB_BLOCK : VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
case QRhiTexture::ASTC_6x6:
return srgb ? VK_FORMAT_ASTC_6x6_SRGB_BLOCK : VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
case QRhiTexture::ASTC_8x5:
return srgb ? VK_FORMAT_ASTC_8x5_SRGB_BLOCK : VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
case QRhiTexture::ASTC_8x6:
return srgb ? VK_FORMAT_ASTC_8x6_SRGB_BLOCK : VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
case QRhiTexture::ASTC_8x8:
return srgb ? VK_FORMAT_ASTC_8x8_SRGB_BLOCK : VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
case QRhiTexture::ASTC_10x5:
return srgb ? VK_FORMAT_ASTC_10x5_SRGB_BLOCK : VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
case QRhiTexture::ASTC_10x6:
return srgb ? VK_FORMAT_ASTC_10x6_SRGB_BLOCK : VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
case QRhiTexture::ASTC_10x8:
return srgb ? VK_FORMAT_ASTC_10x8_SRGB_BLOCK : VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
case QRhiTexture::ASTC_10x10:
return srgb ? VK_FORMAT_ASTC_10x10_SRGB_BLOCK : VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
case QRhiTexture::ASTC_12x10:
return srgb ? VK_FORMAT_ASTC_12x10_SRGB_BLOCK : VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
case QRhiTexture::ASTC_12x12:
return srgb ? VK_FORMAT_ASTC_12x12_SRGB_BLOCK : VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
default:
Q_UNREACHABLE();
return VK_FORMAT_R8G8B8A8_UNORM;
......@@ -1881,10 +1932,33 @@ QMatrix4x4 QRhiVulkan::clipSpaceCorrMatrix() const
return m;
}
bool QRhiVulkan::canTextureFormatBeSupported(QRhiTexture::Format format) const
bool QRhiVulkan::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
Q_UNUSED(format);
return true;
VkPhysicalDeviceFeatures features;
f->vkGetPhysicalDeviceFeatures(physDev, &features);
// Note that with some SDKs the validation layer gives an odd warning about
// BC not being supported, even when our check here succeeds. Not much we
// can do about that.
if (format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7) {
if (!features.textureCompressionBC)
return false;
}
if (format >= QRhiTexture::ETC2_RGB8 && format <= QRhiTexture::ETC2_RGBA8) {
if (!features.textureCompressionETC2)
return false;
}
if (format >= QRhiTexture::ASTC_4x4 && format <= QRhiTexture::ASTC_12x12) {
if (!features.textureCompressionASTC_LDR)
return false;
}
VkFormat vkformat = toVkTextureFormat(format, flags);
VkFormatProperties props;
f->vkGetPhysicalDeviceFormatProperties(physDev, vkformat, &props);
return (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0;
}
QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
......@@ -2623,7 +2697,7 @@ bool QVkTexture::build()
rhiD->f->vkGetPhysicalDeviceFormatProperties(rhiD->physDev, vkformat, &props);
const bool canSampleOptimal = (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
if (!canSampleOptimal) {
qWarning("Texture sampling not supported?!");
qWarning("Texture sampling with optimal tiling for format %d not supported", vkformat);
return false;
}
......
......@@ -358,7 +358,7 @@ public:
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
QMatrix4x4 clipSpaceCorrMatrix() const override;
bool canTextureFormatBeSupported(QRhiTexture::Format format) const override;
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
void create();
void destroy();
......
vk: compressed textures (etc2, astc, bc)
gl, mtl: compressed textures
gl, mtl: srgb (tex, swapchain buf)
rhi without a window, fully offscreen
readbacks
mtl: cubemaps
mtl: targeting cubemap faces
mtl: cbuffers, textures, samplers set should be batched too
......@@ -9,7 +11,6 @@ test cubemap
test cubemap face as target
cbuffer alignment rules - some things fail to translate (to hlsl e.g. with structs), which is fine but how to mitigate
resource import/export, what's the co-op story?
rhi without a window? fully offscreen?
copy-only passes for kicking off transfers early? (copy/transfer queue?)
copyimage (color and ds, no resolve or transforms here)
msaa offscreen (msaa texture? renderbuffer?)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment