Vulkan: Implement TextureView and Framebuffer

This commit is contained in:
Corentin Wallez 2018-01-09 08:37:24 -08:00 committed by Corentin Wallez
parent 49450b5644
commit 35fcfc737b
11 changed files with 194 additions and 3 deletions

View File

@ -297,6 +297,8 @@ if (NXT_ENABLE_VULKAN)
${VULKAN_DIR}/CommandBufferVk.h
${VULKAN_DIR}/FencedDeleter.cpp
${VULKAN_DIR}/FencedDeleter.h
${VULKAN_DIR}/FramebufferVk.cpp
${VULKAN_DIR}/FramebufferVk.h
${VULKAN_DIR}/InputStateVk.cpp
${VULKAN_DIR}/InputStateVk.h
${VULKAN_DIR}/MemoryAllocator.cpp

View File

@ -18,6 +18,7 @@
#include "backend/Builder.h"
#include "backend/Forward.h"
#include "backend/RefCounted.h"
#include "backend/Texture.h"
#include "nxt/nxtcpp.h"

View File

@ -23,7 +23,9 @@ namespace backend { namespace vulkan {
FencedDeleter::~FencedDeleter() {
ASSERT(mBuffersToDelete.Empty());
ASSERT(mFramebuffersToDelete.Empty());
ASSERT(mImagesToDelete.Empty());
ASSERT(mImageViewsToDelete.Empty());
ASSERT(mMemoriesToDelete.Empty());
ASSERT(mPipelineLayoutsToDelete.Empty());
ASSERT(mRenderPassesToDelete.Empty());
@ -37,10 +39,18 @@ namespace backend { namespace vulkan {
mMemoriesToDelete.Enqueue(memory, mDevice->GetSerial());
}
void FencedDeleter::DeleteWhenUnused(VkFramebuffer framebuffer) {
mFramebuffersToDelete.Enqueue(framebuffer, mDevice->GetSerial());
}
void FencedDeleter::DeleteWhenUnused(VkImage image) {
mImagesToDelete.Enqueue(image, mDevice->GetSerial());
}
void FencedDeleter::DeleteWhenUnused(VkImageView view) {
mImageViewsToDelete.Enqueue(view, mDevice->GetSerial());
}
void FencedDeleter::DeleteWhenUnused(VkPipelineLayout layout) {
mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetSerial());
}
@ -77,6 +87,17 @@ namespace backend { namespace vulkan {
mDevice->fn.DestroyRenderPass(vkDevice, renderPass, nullptr);
}
mRenderPassesToDelete.ClearUpTo(completedSerial);
for (VkFramebuffer framebuffer : mFramebuffersToDelete.IterateUpTo(completedSerial)) {
mDevice->fn.DestroyFramebuffer(vkDevice, framebuffer, nullptr);
}
mFramebuffersToDelete.ClearUpTo(completedSerial);
for (VkImageView view : mImageViewsToDelete.IterateUpTo(completedSerial)) {
mDevice->fn.DestroyImageView(vkDevice, view, nullptr);
}
mImageViewsToDelete.ClearUpTo(completedSerial);
}
}} // namespace backend::vulkan

View File

@ -29,7 +29,9 @@ namespace backend { namespace vulkan {
void DeleteWhenUnused(VkBuffer buffer);
void DeleteWhenUnused(VkDeviceMemory memory);
void DeleteWhenUnused(VkFramebuffer framebuffer);
void DeleteWhenUnused(VkImage image);
void DeleteWhenUnused(VkImageView view);
void DeleteWhenUnused(VkPipelineLayout layout);
void DeleteWhenUnused(VkRenderPass renderPass);
@ -38,8 +40,10 @@ namespace backend { namespace vulkan {
private:
Device* mDevice = nullptr;
SerialQueue<VkBuffer> mBuffersToDelete;
SerialQueue<VkFramebuffer> mFramebuffersToDelete;
SerialQueue<VkDeviceMemory> mMemoriesToDelete;
SerialQueue<VkImage> mImagesToDelete;
SerialQueue<VkImageView> mImageViewsToDelete;
SerialQueue<VkPipelineLayout> mPipelineLayoutsToDelete;
SerialQueue<VkRenderPass> mRenderPassesToDelete;
};

View File

@ -0,0 +1,66 @@
// Copyright 2018 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "backend/vulkan/FramebufferVk.h"
#include "backend/vulkan/FencedDeleter.h"
#include "backend/vulkan/RenderPassVk.h"
#include "backend/vulkan/TextureVk.h"
#include "backend/vulkan/VulkanBackend.h"
namespace backend { namespace vulkan {
Framebuffer::Framebuffer(FramebufferBuilder* builder) : FramebufferBase(builder) {
ASSERT(GetRenderPass()->GetAttachmentCount() <= kMaxColorAttachments + 1);
Device* device = ToBackend(GetDevice());
// Fill in the attachment info that will be chained in the create info.
std::array<VkImageView, kMaxColorAttachments + 1> attachments;
for (uint32_t i = 0; i < GetRenderPass()->GetAttachmentCount(); ++i) {
attachments[i] = ToBackend(GetTextureView(i))->GetHandle();
}
// Chain attachments and create the framebuffer
VkFramebufferCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.renderPass = ToBackend(GetRenderPass())->GetHandle();
createInfo.attachmentCount = GetRenderPass()->GetAttachmentCount();
createInfo.pAttachments = attachments.data();
createInfo.width = GetWidth();
createInfo.height = GetHeight();
createInfo.layers = 1;
if (device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
VK_SUCCESS) {
ASSERT(false);
}
}
Framebuffer::~Framebuffer() {
Device* device = ToBackend(GetDevice());
if (mHandle != VK_NULL_HANDLE) {
device->GetFencedDeleter()->DeleteWhenUnused(mHandle);
mHandle = VK_NULL_HANDLE;
}
}
VkFramebuffer Framebuffer::GetHandle() const {
return mHandle;
}
}} // namespace backend::vulkan

View File

@ -0,0 +1,37 @@
// Copyright 2018 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BACKEND_VULKAN_FRAMEBUFFERVK_H_
#define BACKEND_VULKAN_FRAMEBUFFERVK_H_
#include "backend/Framebuffer.h"
#include "backend/vulkan/vulkan_platform.h"
namespace backend { namespace vulkan {
class Framebuffer : public FramebufferBase {
public:
Framebuffer(FramebufferBuilder* builder);
~Framebuffer();
VkFramebuffer GetHandle() const;
private:
VkFramebuffer mHandle = VK_NULL_HANDLE;
};
}} // namespace backend::vulkan
#endif // BACKEND_VULKAN_FRAMEBUFFERVK_H_

View File

@ -14,6 +14,7 @@
#include "backend/vulkan/BufferVk.h"
#include "backend/vulkan/CommandBufferVk.h"
#include "backend/vulkan/FramebufferVk.h"
#include "backend/vulkan/InputStateVk.h"
#include "backend/vulkan/PipelineLayoutVk.h"
#include "backend/vulkan/RenderPassVk.h"

View File

@ -32,6 +32,17 @@ namespace backend { namespace vulkan {
}
}
// Converts an NXT texture dimension to a Vulkan image view type.
// Contrary to image types, image view types include arrayness and cubemapness
VkImageViewType VulkanImageViewType(nxt::TextureDimension dimension) {
switch (dimension) {
case nxt::TextureDimension::e2D:
return VK_IMAGE_VIEW_TYPE_2D;
default:
UNREACHABLE();
}
}
// Converts the NXT usage flags to Vulkan usage flags. Also needs the format to choose
// between color and depth attachment usages.
VkImageUsageFlags VulkanImageUsage(nxt::TextureUsageBit usage, nxt::TextureFormat format) {
@ -302,4 +313,41 @@ namespace backend { namespace vulkan {
RecordBarrier(commands, currentUsage, targetUsage);
}
TextureView::TextureView(TextureViewBuilder* builder) : TextureViewBase(builder) {
Device* device = ToBackend(builder->GetDevice());
VkImageViewCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.image = ToBackend(GetTexture())->GetHandle();
createInfo.viewType = VulkanImageViewType(GetTexture()->GetDimension());
createInfo.format = VulkanImageFormat(GetTexture()->GetFormat());
createInfo.components = VkComponentMapping{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
createInfo.subresourceRange.aspectMask = VulkanAspectMask(GetTexture()->GetFormat());
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = GetTexture()->GetNumMipLevels();
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;
if (device->fn.CreateImageView(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
VK_SUCCESS) {
ASSERT(false);
}
}
TextureView::~TextureView() {
Device* device = ToBackend(GetTexture()->GetDevice());
if (mHandle != VK_NULL_HANDLE) {
device->GetFencedDeleter()->DeleteWhenUnused(mHandle);
mHandle = VK_NULL_HANDLE;
}
}
VkImageView TextureView::GetHandle() const {
return mHandle;
}
}} // namespace backend::vulkan

View File

@ -44,6 +44,17 @@ namespace backend { namespace vulkan {
DeviceMemoryAllocation mMemoryAllocation;
};
class TextureView : public TextureViewBase {
public:
TextureView(TextureViewBuilder* builder);
~TextureView();
VkImageView GetHandle() const;
private:
VkImageView mHandle = VK_NULL_HANDLE;
};
}} // namespace backend::vulkan
#endif // BACKEND_VULKAN_TEXTUREVK_H_

View File

@ -19,6 +19,7 @@
#include "backend/vulkan/BufferVk.h"
#include "backend/vulkan/CommandBufferVk.h"
#include "backend/vulkan/FencedDeleter.h"
#include "backend/vulkan/FramebufferVk.h"
#include "backend/vulkan/InputStateVk.h"
#include "backend/vulkan/PipelineLayoutVk.h"
#include "backend/vulkan/RenderPassVk.h"

View File

@ -23,7 +23,6 @@
#include "backend/ComputePipeline.h"
#include "backend/DepthStencilState.h"
#include "backend/Device.h"
#include "backend/Framebuffer.h"
#include "backend/Queue.h"
#include "backend/RenderPipeline.h"
#include "backend/Sampler.h"
@ -49,7 +48,7 @@ namespace backend { namespace vulkan {
using ComputePipeline = ComputePipelineBase;
using DepthStencilState = DepthStencilStateBase;
class Device;
using Framebuffer = FramebufferBase;
class Framebuffer;
class InputState;
class PipelineLayout;
class Queue;
@ -59,7 +58,7 @@ namespace backend { namespace vulkan {
using ShaderModule = ShaderModuleBase;
class SwapChain;
class Texture;
using TextureView = TextureViewBase;
class TextureView;
class BufferUploader;
class FencedDeleter;