Commit 22deb701 authored by Laszlo Agocs's avatar Laszlo Agocs
Browse files

vk: implement texture import/export

parent 3da335d4
......@@ -1338,7 +1338,7 @@ void QMetalTexture::release()
e.type = QRhiMetalData::DeferredReleaseEntry::Texture;
e.lastActiveFrameSlot = lastActiveFrameSlot;
e.texture.texture = d->tex;
e.texture.texture = d->owns ? d->tex : nil;
d->tex = nil;
nativeHandlesStruct.texture = nullptr;
......@@ -1347,10 +1347,8 @@ void QMetalTexture::release()
d->stagingBuf[i] = nil;
}
if (d->owns) {
QRHI_RES_RHI(QRhiMetal);
rhiD->d->releaseQueue.append(e);
}
QRHI_RES_RHI(QRhiMetal);
rhiD->d->releaseQueue.append(e);
}
static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags)
......
......@@ -3378,9 +3378,9 @@ void QVkTexture::release()
e.type = QRhiVulkan::DeferredReleaseEntry::Texture;
e.lastActiveFrameSlot = lastActiveFrameSlot;
e.texture.image = image;
e.texture.image = owns ? image : VK_NULL_HANDLE;
e.texture.imageView = imageView;
e.texture.allocation = imageAlloc;
e.texture.allocation = owns ? imageAlloc : nullptr;
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) {
e.texture.stagingBuffers[i] = stagingBuffers[i];
......@@ -3393,12 +3393,13 @@ void QVkTexture::release()
image = VK_NULL_HANDLE;
imageView = VK_NULL_HANDLE;
imageAlloc = nullptr;
nativeHandlesStruct.image = VK_NULL_HANDLE;
QRHI_RES_RHI(QRhiVulkan);
rhiD->releaseQueue.append(e);
}
bool QVkTexture::build()
bool QVkTexture::prepareBuild(QSize *adjustedSize)
{
if (image)
release();
......@@ -3414,7 +3415,6 @@ bool QVkTexture::build()
}
const QSize size = m_pixelSize.isEmpty() ? QSize(16, 16) : m_pixelSize;
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
......@@ -3431,6 +3431,59 @@ bool QVkTexture::build()
}
}
if (adjustedSize)
*adjustedSize = size;
return true;
}
bool QVkTexture::finishBuild()
{
QRHI_RES_RHI(QRhiVulkan);
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
VkImageViewCreateInfo viewInfo;
memset(&viewInfo, 0, sizeof(viewInfo));
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
viewInfo.viewType = isCube ? VK_IMAGE_VIEW_TYPE_CUBE : VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
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.levelCount = mipLevelCount;
viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &imageView);
if (err != VK_SUCCESS) {
qWarning("Failed to create image view: %d", err);
return false;
}
nativeHandlesStruct.image = image;
lastActiveFrameSlot = -1;
generation += 1;
return true;
}
bool QVkTexture::build()
{
QRHI_RES_RHI(QRhiVulkan);
QSize size;
if (!prepareBuild(&size))
return false;
const bool isRenderTarget = m_flags.testFlag(QRhiTexture::RenderTarget);
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
VkImageCreateInfo imageInfo;
memset(&imageInfo, 0, sizeof(imageInfo));
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
......@@ -3447,7 +3500,7 @@ bool QVkTexture::build()
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (m_flags.testFlag(QRhiTexture::RenderTarget)) {
if (isRenderTarget) {
if (isDepth)
imageInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
else
......@@ -3470,32 +3523,39 @@ bool QVkTexture::build()
}
imageAlloc = allocation;
VkImageViewCreateInfo viewInfo;
memset(&viewInfo, 0, sizeof(viewInfo));
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
viewInfo.viewType = isCube ? VK_IMAGE_VIEW_TYPE_CUBE : VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
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.levelCount = mipLevelCount;
viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &imageView);
if (err != VK_SUCCESS) {
qWarning("Failed to create image view: %d", err);
if (!finishBuild())
return false;
}
owns = true;
layout = VK_IMAGE_LAYOUT_PREINITIALIZED;
lastActiveFrameSlot = -1;
generation += 1;
return true;
}
bool QVkTexture::buildFrom(QRhiNativeHandles *src)
{
QRhiVulkanTextureNativeHandles *h = static_cast<QRhiVulkanTextureNativeHandles *>(src);
if (!h || !h->image)
return false;
if (!prepareBuild())
return false;
image = h->image;
if (!finishBuild())
return false;
owns = false;
layout = h->layout;
return true;
}
QRhiNativeHandles *QVkTexture::nativeHandles()
{
nativeHandlesStruct.layout = layout;
return &nativeHandlesStruct;
}
QVkSampler::QVkSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
AddressMode u, AddressMode v, AddressMode w)
: QRhiSampler(rhi, magFilter, minFilter, mipmapMode, u, v, w)
......
......@@ -72,6 +72,12 @@ struct Q_RHI_EXPORT QRhiVulkanNativeHandles : public QRhiNativeHandles
void *vmemAllocator;
};
struct Q_RHI_EXPORT QRhiVulkanTextureNativeHandles : public QRhiNativeHandles
{
VkImage image = VK_NULL_HANDLE;
VkImageLayout layout = VK_IMAGE_LAYOUT_PREINITIALIZED;
};
QT_END_NAMESPACE
#endif
......@@ -103,12 +103,19 @@ struct QVkTexture : public QRhiTexture
int sampleCount, Flags flags);
void release() override;
bool build() override;
bool buildFrom(QRhiNativeHandles *src) override;
QRhiNativeHandles *nativeHandles() override;
bool prepareBuild(QSize *adjustedSize = nullptr);
bool finishBuild();
VkImage image = VK_NULL_HANDLE;
VkImageView imageView = VK_NULL_HANDLE;
QVkAlloc imageAlloc = nullptr;
VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT];
QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT];
bool owns = true;
QRhiVulkanTextureNativeHandles nativeHandlesStruct;
VkImageLayout layout = VK_IMAGE_LAYOUT_PREINITIALIZED;
VkFormat vkformat;
uint mipLevelCount = 0;
......
......@@ -49,7 +49,7 @@ dxc for d3d as an alternative to fxc?
hlsl -> dxc -> spirv -> spirv-cross hmmm...
+++ done
mtl: texture import/export
mtl, gl, vk: texture import/export
rhi native handle getter (device, ...)
imgui example
vk: shouldn't just qFatal
......
Supports Markdown
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