Vulkan: Implement TextureView and Framebuffer
This commit is contained in:
parent
49450b5644
commit
35fcfc737b
|
@ -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
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "backend/Builder.h"
|
||||
#include "backend/Forward.h"
|
||||
#include "backend/RefCounted.h"
|
||||
#include "backend/Texture.h"
|
||||
|
||||
#include "nxt/nxtcpp.h"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue