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}/CommandBufferVk.h
|
||||||
${VULKAN_DIR}/FencedDeleter.cpp
|
${VULKAN_DIR}/FencedDeleter.cpp
|
||||||
${VULKAN_DIR}/FencedDeleter.h
|
${VULKAN_DIR}/FencedDeleter.h
|
||||||
|
${VULKAN_DIR}/FramebufferVk.cpp
|
||||||
|
${VULKAN_DIR}/FramebufferVk.h
|
||||||
${VULKAN_DIR}/InputStateVk.cpp
|
${VULKAN_DIR}/InputStateVk.cpp
|
||||||
${VULKAN_DIR}/InputStateVk.h
|
${VULKAN_DIR}/InputStateVk.h
|
||||||
${VULKAN_DIR}/MemoryAllocator.cpp
|
${VULKAN_DIR}/MemoryAllocator.cpp
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
#include "backend/Forward.h"
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
#include "backend/Texture.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@ namespace backend { namespace vulkan {
|
||||||
|
|
||||||
FencedDeleter::~FencedDeleter() {
|
FencedDeleter::~FencedDeleter() {
|
||||||
ASSERT(mBuffersToDelete.Empty());
|
ASSERT(mBuffersToDelete.Empty());
|
||||||
|
ASSERT(mFramebuffersToDelete.Empty());
|
||||||
ASSERT(mImagesToDelete.Empty());
|
ASSERT(mImagesToDelete.Empty());
|
||||||
|
ASSERT(mImageViewsToDelete.Empty());
|
||||||
ASSERT(mMemoriesToDelete.Empty());
|
ASSERT(mMemoriesToDelete.Empty());
|
||||||
ASSERT(mPipelineLayoutsToDelete.Empty());
|
ASSERT(mPipelineLayoutsToDelete.Empty());
|
||||||
ASSERT(mRenderPassesToDelete.Empty());
|
ASSERT(mRenderPassesToDelete.Empty());
|
||||||
|
@ -37,10 +39,18 @@ namespace backend { namespace vulkan {
|
||||||
mMemoriesToDelete.Enqueue(memory, mDevice->GetSerial());
|
mMemoriesToDelete.Enqueue(memory, mDevice->GetSerial());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FencedDeleter::DeleteWhenUnused(VkFramebuffer framebuffer) {
|
||||||
|
mFramebuffersToDelete.Enqueue(framebuffer, mDevice->GetSerial());
|
||||||
|
}
|
||||||
|
|
||||||
void FencedDeleter::DeleteWhenUnused(VkImage image) {
|
void FencedDeleter::DeleteWhenUnused(VkImage image) {
|
||||||
mImagesToDelete.Enqueue(image, mDevice->GetSerial());
|
mImagesToDelete.Enqueue(image, mDevice->GetSerial());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FencedDeleter::DeleteWhenUnused(VkImageView view) {
|
||||||
|
mImageViewsToDelete.Enqueue(view, mDevice->GetSerial());
|
||||||
|
}
|
||||||
|
|
||||||
void FencedDeleter::DeleteWhenUnused(VkPipelineLayout layout) {
|
void FencedDeleter::DeleteWhenUnused(VkPipelineLayout layout) {
|
||||||
mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetSerial());
|
mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetSerial());
|
||||||
}
|
}
|
||||||
|
@ -77,6 +87,17 @@ namespace backend { namespace vulkan {
|
||||||
mDevice->fn.DestroyRenderPass(vkDevice, renderPass, nullptr);
|
mDevice->fn.DestroyRenderPass(vkDevice, renderPass, nullptr);
|
||||||
}
|
}
|
||||||
mRenderPassesToDelete.ClearUpTo(completedSerial);
|
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
|
}} // namespace backend::vulkan
|
||||||
|
|
|
@ -29,7 +29,9 @@ namespace backend { namespace vulkan {
|
||||||
|
|
||||||
void DeleteWhenUnused(VkBuffer buffer);
|
void DeleteWhenUnused(VkBuffer buffer);
|
||||||
void DeleteWhenUnused(VkDeviceMemory memory);
|
void DeleteWhenUnused(VkDeviceMemory memory);
|
||||||
|
void DeleteWhenUnused(VkFramebuffer framebuffer);
|
||||||
void DeleteWhenUnused(VkImage image);
|
void DeleteWhenUnused(VkImage image);
|
||||||
|
void DeleteWhenUnused(VkImageView view);
|
||||||
void DeleteWhenUnused(VkPipelineLayout layout);
|
void DeleteWhenUnused(VkPipelineLayout layout);
|
||||||
void DeleteWhenUnused(VkRenderPass renderPass);
|
void DeleteWhenUnused(VkRenderPass renderPass);
|
||||||
|
|
||||||
|
@ -38,8 +40,10 @@ namespace backend { namespace vulkan {
|
||||||
private:
|
private:
|
||||||
Device* mDevice = nullptr;
|
Device* mDevice = nullptr;
|
||||||
SerialQueue<VkBuffer> mBuffersToDelete;
|
SerialQueue<VkBuffer> mBuffersToDelete;
|
||||||
|
SerialQueue<VkFramebuffer> mFramebuffersToDelete;
|
||||||
SerialQueue<VkDeviceMemory> mMemoriesToDelete;
|
SerialQueue<VkDeviceMemory> mMemoriesToDelete;
|
||||||
SerialQueue<VkImage> mImagesToDelete;
|
SerialQueue<VkImage> mImagesToDelete;
|
||||||
|
SerialQueue<VkImageView> mImageViewsToDelete;
|
||||||
SerialQueue<VkPipelineLayout> mPipelineLayoutsToDelete;
|
SerialQueue<VkPipelineLayout> mPipelineLayoutsToDelete;
|
||||||
SerialQueue<VkRenderPass> mRenderPassesToDelete;
|
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/BufferVk.h"
|
||||||
#include "backend/vulkan/CommandBufferVk.h"
|
#include "backend/vulkan/CommandBufferVk.h"
|
||||||
|
#include "backend/vulkan/FramebufferVk.h"
|
||||||
#include "backend/vulkan/InputStateVk.h"
|
#include "backend/vulkan/InputStateVk.h"
|
||||||
#include "backend/vulkan/PipelineLayoutVk.h"
|
#include "backend/vulkan/PipelineLayoutVk.h"
|
||||||
#include "backend/vulkan/RenderPassVk.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
|
// Converts the NXT usage flags to Vulkan usage flags. Also needs the format to choose
|
||||||
// between color and depth attachment usages.
|
// between color and depth attachment usages.
|
||||||
VkImageUsageFlags VulkanImageUsage(nxt::TextureUsageBit usage, nxt::TextureFormat format) {
|
VkImageUsageFlags VulkanImageUsage(nxt::TextureUsageBit usage, nxt::TextureFormat format) {
|
||||||
|
@ -302,4 +313,41 @@ namespace backend { namespace vulkan {
|
||||||
RecordBarrier(commands, currentUsage, targetUsage);
|
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
|
}} // namespace backend::vulkan
|
||||||
|
|
|
@ -44,6 +44,17 @@ namespace backend { namespace vulkan {
|
||||||
DeviceMemoryAllocation mMemoryAllocation;
|
DeviceMemoryAllocation mMemoryAllocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureView : public TextureViewBase {
|
||||||
|
public:
|
||||||
|
TextureView(TextureViewBuilder* builder);
|
||||||
|
~TextureView();
|
||||||
|
|
||||||
|
VkImageView GetHandle() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkImageView mHandle = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
}} // namespace backend::vulkan
|
}} // namespace backend::vulkan
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_TEXTUREVK_H_
|
#endif // BACKEND_VULKAN_TEXTUREVK_H_
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "backend/vulkan/BufferVk.h"
|
#include "backend/vulkan/BufferVk.h"
|
||||||
#include "backend/vulkan/CommandBufferVk.h"
|
#include "backend/vulkan/CommandBufferVk.h"
|
||||||
#include "backend/vulkan/FencedDeleter.h"
|
#include "backend/vulkan/FencedDeleter.h"
|
||||||
|
#include "backend/vulkan/FramebufferVk.h"
|
||||||
#include "backend/vulkan/InputStateVk.h"
|
#include "backend/vulkan/InputStateVk.h"
|
||||||
#include "backend/vulkan/PipelineLayoutVk.h"
|
#include "backend/vulkan/PipelineLayoutVk.h"
|
||||||
#include "backend/vulkan/RenderPassVk.h"
|
#include "backend/vulkan/RenderPassVk.h"
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "backend/ComputePipeline.h"
|
#include "backend/ComputePipeline.h"
|
||||||
#include "backend/DepthStencilState.h"
|
#include "backend/DepthStencilState.h"
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
#include "backend/Framebuffer.h"
|
|
||||||
#include "backend/Queue.h"
|
#include "backend/Queue.h"
|
||||||
#include "backend/RenderPipeline.h"
|
#include "backend/RenderPipeline.h"
|
||||||
#include "backend/Sampler.h"
|
#include "backend/Sampler.h"
|
||||||
|
@ -49,7 +48,7 @@ namespace backend { namespace vulkan {
|
||||||
using ComputePipeline = ComputePipelineBase;
|
using ComputePipeline = ComputePipelineBase;
|
||||||
using DepthStencilState = DepthStencilStateBase;
|
using DepthStencilState = DepthStencilStateBase;
|
||||||
class Device;
|
class Device;
|
||||||
using Framebuffer = FramebufferBase;
|
class Framebuffer;
|
||||||
class InputState;
|
class InputState;
|
||||||
class PipelineLayout;
|
class PipelineLayout;
|
||||||
class Queue;
|
class Queue;
|
||||||
|
@ -59,7 +58,7 @@ namespace backend { namespace vulkan {
|
||||||
using ShaderModule = ShaderModuleBase;
|
using ShaderModule = ShaderModuleBase;
|
||||||
class SwapChain;
|
class SwapChain;
|
||||||
class Texture;
|
class Texture;
|
||||||
using TextureView = TextureViewBase;
|
class TextureView;
|
||||||
|
|
||||||
class BufferUploader;
|
class BufferUploader;
|
||||||
class FencedDeleter;
|
class FencedDeleter;
|
||||||
|
|
Loading…
Reference in New Issue