Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiview support for vulkan #7892

Merged
merged 14 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions filament/backend/src/vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ VkExtent2D VulkanAttachment::getExtent2D() const {

VkImageView VulkanAttachment::getImageView() {
assert_invariant(texture);
return texture->getAttachmentView(getSubresourceRange());
VkImageSubresourceRange range = getSubresourceRange();
if (range.layerCount > 1) {
return texture->getMultiviewAttachmentView(range);
}
return texture->getAttachmentView(range);
}

bool VulkanAttachment::isDepth() const {
Expand All @@ -73,7 +77,7 @@ VkImageSubresourceRange VulkanAttachment::getSubresourceRange() const {
.baseMipLevel = uint32_t(level),
.levelCount = 1,
.baseArrayLayer = uint32_t(layer),
.layerCount = 1,
.layerCount = layerCount,
};
}

Expand Down
2 changes: 2 additions & 0 deletions filament/backend/src/vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ struct VulkanCommandBuffer;
struct VulkanAttachment {
VulkanTexture* texture = nullptr;
uint8_t level = 0;
uint8_t baseViewIndex = 0;
uint8_t layerCount = 1;
uint16_t layer = 0;

GrantComm marked this conversation as resolved.
Show resolved Hide resolved
bool isDepth() const;
Expand Down
14 changes: 13 additions & 1 deletion filament/backend/src/vulkan/VulkanDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,8 @@ void VulkanDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
colorTargets[i] = {
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
.texture = mResourceAllocator.handle_cast<VulkanTexture*>(color[i].handle),
.level = color[i].level,
.baseViewIndex = color[i].baseViewIndex,
.layerCount = layerCount,
.layer = color[i].layer,
};
UTILS_UNUSED_IN_RELEASE VkExtent2D extent = colorTargets[i].getExtent2D();
Expand All @@ -609,6 +611,8 @@ void VulkanDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
depthStencil[0] = {
.texture = mResourceAllocator.handle_cast<VulkanTexture*>(depth.handle),
.level = depth.level,
.baseViewIndex = depth.baseViewIndex,
.layerCount = layerCount,
poweifeng marked this conversation as resolved.
Show resolved Hide resolved
.layer = depth.layer,
};
UTILS_UNUSED_IN_RELEASE VkExtent2D extent = depthStencil[0].getExtent2D();
Expand All @@ -621,6 +625,8 @@ void VulkanDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
depthStencil[1] = {
.texture = mResourceAllocator.handle_cast<VulkanTexture*>(stencil.handle),
.level = stencil.level,
.baseViewIndex = stencil.baseViewIndex,
poweifeng marked this conversation as resolved.
Show resolved Hide resolved
.layerCount = layerCount,
.layer = stencil.layer,
};
UTILS_UNUSED_IN_RELEASE VkExtent2D extent = depthStencil[1].getExtent2D();
Expand All @@ -637,7 +643,7 @@ void VulkanDriver::createRenderTargetR(Handle<HwRenderTarget> rth,

auto renderTarget = mResourceAllocator.construct<VulkanRenderTarget>(rth, mPlatform->getDevice(),
mPlatform->getPhysicalDevice(), mContext, mAllocator, &mCommands, width, height,
samples, colorTargets, depthStencil, mStagePool);
samples, colorTargets, depthStencil, mStagePool, layerCount);
mResourceManager.acquire(renderTarget);
}

Expand Down Expand Up @@ -1267,6 +1273,8 @@ void VulkanDriver::beginRenderPass(Handle<HwRenderTarget> rth, const RenderPassP
}
}

uint8_t renderTargetLayerCount = rt->getLayerCount();
GrantComm marked this conversation as resolved.
Show resolved Hide resolved

// Create the VkRenderPass or fetch it from cache.
VulkanFboCache::RenderPassKey rpkey = {
.initialColorLayoutMask = 0,
Expand All @@ -1277,10 +1285,14 @@ void VulkanDriver::beginRenderPass(Handle<HwRenderTarget> rth, const RenderPassP
.discardEnd = discardEndVal,
.samples = rt->getSamples(),
.subpassMask = uint8_t(params.subpassMask),
.viewCount = renderTargetLayerCount,
};

for (int i = 0; i < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) {
const VulkanAttachment& info = rt->getColor(i);

if (info.texture) {
assert_invariant(info.layerCount == renderTargetLayerCount);
rpkey.initialColorLayoutMask |= 1 << i;
rpkey.colorFormat[i] = info.getFormat();
if (rpkey.samples > 1 && info.texture->samples == 1) {
Expand Down
29 changes: 26 additions & 3 deletions filament/backend/src/vulkan/VulkanFboCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ bool VulkanFboCache::RenderPassEq::operator()(const RenderPassKey& k1,
if (k1.samples != k2.samples) return false;
if (k1.needsResolveMask != k2.needsResolveMask) return false;
if (k1.subpassMask != k2.subpassMask) return false;
if (k1.viewCount != k2.viewCount) return false;
return true;
}

Expand Down Expand Up @@ -183,9 +184,28 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey config) noexcept {
.subpassCount = hasSubpasses ? 2u : 1u,
.pSubpasses = subpasses,
.dependencyCount = hasSubpasses ? 1u : 0u,
.pDependencies = dependencies
.pDependencies = dependencies,
};

VkRenderPassMultiviewCreateInfo multiviewCreateInfo = {};
uint32_t subpassViewMask = (1 << config.viewCount) - 1;
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
// Prepare a view mask array for the maximum number of subpasses. All subpasses have all views
// activated.
uint32_t viewMasks[2] = {subpassViewMask, subpassViewMask};
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
if (config.viewCount > 1) {
// Fill the multiview create info.
multiviewCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
multiviewCreateInfo.pNext = nullptr;
multiviewCreateInfo.subpassCount = hasSubpasses ? 2u : 1u;
multiviewCreateInfo.pViewMasks = viewMasks;
multiviewCreateInfo.dependencyCount = 0;
multiviewCreateInfo.pViewOffsets = nullptr;
multiviewCreateInfo.correlationMaskCount = 1;
multiviewCreateInfo.pCorrelationMasks = &subpassViewMask;

renderPassInfo.pNext = &multiviewCreateInfo;
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
}

int attachmentIndex = 0;

// Populate the Color Attachments.
Expand Down Expand Up @@ -288,16 +308,19 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey config) noexcept {
const bool clear = any(config.clear & TargetBufferFlags::DEPTH);
const bool discardStart = any(config.discardStart & TargetBufferFlags::DEPTH);
const bool discardEnd = any(config.discardEnd & TargetBufferFlags::DEPTH);
const VkAttachmentLoadOp loadOp = clear ? kClear : (discardStart ? kDontCare : kKeep);
depthAttachmentRef.layout = imgutil::getVkLayout(VulkanLayout::DEPTH_ATTACHMENT);
depthAttachmentRef.attachment = attachmentIndex;
VkImageLayout initialLayout = imgutil::getVkLayout(config.initialDepthLayout);
GrantComm marked this conversation as resolved.
Show resolved Hide resolved

attachments[attachmentIndex++] = {
.format = config.depthFormat,
.samples = (VkSampleCountFlagBits) config.samples,
.loadOp = clear ? kClear : (discardStart ? kDontCare : kKeep),
.loadOp = loadOp,
.storeOp = discardEnd ? kDisableStore : kEnableStore,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = imgutil::getVkLayout(config.initialDepthLayout),
.initialLayout = initialLayout,
.finalLayout = imgutil::getVkLayout(FINAL_DEPTH_ATTACHMENT_LAYOUT),
};
}
Expand Down
2 changes: 1 addition & 1 deletion filament/backend/src/vulkan/VulkanFboCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class VulkanFboCache {
uint8_t samples; // 1 byte
uint8_t needsResolveMask; // 1 byte
uint8_t subpassMask; // 1 byte
uint8_t padding2; // 1 byte
uint8_t viewCount; // 1 byte
};
struct RenderPassVal {
VkRenderPass handle;
Expand Down
5 changes: 3 additions & 2 deletions filament/backend/src/vulkan/VulkanHandles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,12 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica
VulkanContext const& context, VmaAllocator allocator, VulkanCommands* commands,
uint32_t width, uint32_t height, uint8_t samples,
VulkanAttachment color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT],
VulkanAttachment depthStencil[2], VulkanStagePool& stagePool)
VulkanAttachment depthStencil[2], VulkanStagePool& stagePool, uint8_t layerCount)
: HwRenderTarget(width, height),
VulkanResource(VulkanResourceType::RENDER_TARGET),
mOffscreen(true),
mSamples(samples) {
mSamples(samples),
mLayerCount(layerCount) {
for (int index = 0; index < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; index++) {
mColor[index] = color[index];
}
Expand Down
4 changes: 3 additions & 1 deletion filament/backend/src/vulkan/VulkanHandles.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ struct VulkanRenderTarget : private HwRenderTarget, VulkanResource {
VulkanContext const& context, VmaAllocator allocator,
VulkanCommands* commands, uint32_t width, uint32_t height,
uint8_t samples, VulkanAttachment color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT],
VulkanAttachment depthStencil[2], VulkanStagePool& stagePool);
VulkanAttachment depthStencil[2], VulkanStagePool& stagePool, uint8_t layerCount);

// Creates a special "default" render target (i.e. associated with the swap chain)
explicit VulkanRenderTarget();
Expand All @@ -319,6 +319,7 @@ struct VulkanRenderTarget : private HwRenderTarget, VulkanResource {
VulkanAttachment& getMsaaDepth();
uint8_t getColorTargetCount(const VulkanRenderPass& pass) const;
uint8_t getSamples() const { return mSamples; }
uint8_t getLayerCount() { return mLayerCount; }
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
bool hasDepth() const { return mDepth.texture; }
bool isSwapChain() const { return !mOffscreen; }
void bindToSwapChain(VulkanSwapChain& surf);
Expand All @@ -330,6 +331,7 @@ struct VulkanRenderTarget : private HwRenderTarget, VulkanResource {
VulkanAttachment mMsaaDepthAttachment = {};
const bool mOffscreen : 1;
uint8_t mSamples : 7;
uint8_t mLayerCount = 1;
};

struct VulkanBufferObject;
Expand Down
9 changes: 6 additions & 3 deletions filament/backend/src/vulkan/VulkanTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
mStagePool(stagePool),
mDevice(device),
mAllocator(allocator),
mCommands(commands) {

mCommands(commands)
{
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
// Create an appropriately-sized device-only VkImage, but do not fill it yet.
VkImageCreateInfo imageInfo{.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = target == SamplerType::SAMPLER_3D ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D,
Expand Down Expand Up @@ -387,12 +387,15 @@ void VulkanTexture::setPrimaryRange(uint32_t minMiplevel, uint32_t maxMiplevel)
}

VkImageView VulkanTexture::getAttachmentView(VkImageSubresourceRange range) {
GrantComm marked this conversation as resolved.
Show resolved Hide resolved
// Attachments should only have one mipmap level and one layer.
range.levelCount = 1;
range.layerCount = 1;
return getImageView(range, VK_IMAGE_VIEW_TYPE_2D, {});
}

VkImageView VulkanTexture::getMultiviewAttachmentView(VkImageSubresourceRange range) {
return getImageView(range, VK_IMAGE_VIEW_TYPE_2D_ARRAY, {});
}

VkImageView VulkanTexture::getViewForType(VkImageSubresourceRange const& range, VkImageViewType type) {
return getImageView(range, type, mSwizzle);
}
Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/vulkan/VulkanTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ struct VulkanTexture : public HwTexture, VulkanResource {
// and the identity swizzle.
VkImageView getAttachmentView(VkImageSubresourceRange range);

// Gets or creates a cached VkImageView for a single subresource that can be used as a render
// target attachment when rendering with multiview.
VkImageView getMultiviewAttachmentView(VkImageSubresourceRange range);

// This is a workaround for the first few frames where we're waiting for the texture to actually
// be uploaded. In that case, we bind the sampler to an empty texture, but the corresponding
// imageView needs to be of the right type. Hence, we provide an option to indicate the
Expand Down
2 changes: 1 addition & 1 deletion filament/src/fg/FrameGraphRenderPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct FrameGraphRenderPass {
Viewport viewport{};
math::float4 clearColor{};
uint8_t samples = 0; // # of samples (0 = unset, default)
uint8_t layerCount = 0; // # of layer (# > 1 = multiview)
uint8_t layerCount = 1; // # of layer (# > 1 = multiview)
backend::TargetBufferFlags clearFlags{};
backend::TargetBufferFlags discardStart{};
};
Expand Down