mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-15 11:51:22 +00:00
Format: src/backend/vulkan
This commit is contained in:
parent
c7807abf04
commit
23b27a27e2
@ -19,19 +19,21 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
BufferUploader::BufferUploader(Device* device)
|
BufferUploader::BufferUploader(Device* device) : mDevice(device) {
|
||||||
: mDevice(device) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferUploader::~BufferUploader() {
|
BufferUploader::~BufferUploader() {
|
||||||
ASSERT(mBuffersToDelete.Empty());
|
ASSERT(mBuffersToDelete.Empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferUploader::BufferSubData(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, const void* data) {
|
void BufferUploader::BufferSubData(VkBuffer buffer,
|
||||||
// TODO(cwallez@chromium.org): this is soooooo bad. We should use some sort of ring buffer for this.
|
VkDeviceSize offset,
|
||||||
|
VkDeviceSize size,
|
||||||
|
const void* data) {
|
||||||
|
// TODO(cwallez@chromium.org): this is soooooo bad. We should use some sort of ring buffer
|
||||||
|
// for this.
|
||||||
|
|
||||||
// Create a staging buffer
|
// Create a staging buffer
|
||||||
VkBufferCreateInfo createInfo;
|
VkBufferCreateInfo createInfo;
|
||||||
@ -45,20 +47,23 @@ namespace vulkan {
|
|||||||
createInfo.pQueueFamilyIndices = 0;
|
createInfo.pQueueFamilyIndices = 0;
|
||||||
|
|
||||||
VkBuffer stagingBuffer = VK_NULL_HANDLE;
|
VkBuffer stagingBuffer = VK_NULL_HANDLE;
|
||||||
if (mDevice->fn.CreateBuffer(mDevice->GetVkDevice(), &createInfo, nullptr, &stagingBuffer) != VK_SUCCESS) {
|
if (mDevice->fn.CreateBuffer(mDevice->GetVkDevice(), &createInfo, nullptr,
|
||||||
|
&stagingBuffer) != VK_SUCCESS) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkMemoryRequirements requirements;
|
VkMemoryRequirements requirements;
|
||||||
mDevice->fn.GetBufferMemoryRequirements(mDevice->GetVkDevice(), stagingBuffer, &requirements);
|
mDevice->fn.GetBufferMemoryRequirements(mDevice->GetVkDevice(), stagingBuffer,
|
||||||
|
&requirements);
|
||||||
|
|
||||||
DeviceMemoryAllocation allocation;
|
DeviceMemoryAllocation allocation;
|
||||||
if (!mDevice->GetMemoryAllocator()->Allocate(requirements, true, &allocation)) {
|
if (!mDevice->GetMemoryAllocator()->Allocate(requirements, true, &allocation)) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDevice->fn.BindBufferMemory(mDevice->GetVkDevice(), stagingBuffer, allocation.GetMemory(),
|
if (mDevice->fn.BindBufferMemory(mDevice->GetVkDevice(), stagingBuffer,
|
||||||
allocation.GetMemoryOffset()) != VK_SUCCESS) {
|
allocation.GetMemory(),
|
||||||
|
allocation.GetMemoryOffset()) != VK_SUCCESS) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,11 +80,9 @@ namespace vulkan {
|
|||||||
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
|
|
||||||
mDevice->fn.CmdPipelineBarrier(commands,
|
mDevice->fn.CmdPipelineBarrier(commands, VK_PIPELINE_STAGE_HOST_BIT,
|
||||||
VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &barrier, 0, nullptr,
|
||||||
1, &barrier,
|
0, nullptr);
|
||||||
0, nullptr,
|
|
||||||
0, nullptr);
|
|
||||||
|
|
||||||
VkBufferCopy copy;
|
VkBufferCopy copy;
|
||||||
copy.srcOffset = 0;
|
copy.srcOffset = 0;
|
||||||
@ -100,5 +103,4 @@ namespace vulkan {
|
|||||||
mBuffersToDelete.ClearUpTo(completedSerial);
|
mBuffersToDelete.ClearUpTo(completedSerial);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
@ -18,26 +18,27 @@
|
|||||||
#include "backend/vulkan/vulkan_platform.h"
|
#include "backend/vulkan/vulkan_platform.h"
|
||||||
#include "common/SerialQueue.h"
|
#include "common/SerialQueue.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
|
||||||
class BufferUploader {
|
class BufferUploader {
|
||||||
public:
|
public:
|
||||||
BufferUploader(Device* device);
|
BufferUploader(Device* device);
|
||||||
~BufferUploader();
|
~BufferUploader();
|
||||||
|
|
||||||
void BufferSubData(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, const void* data);
|
void BufferSubData(VkBuffer buffer,
|
||||||
|
VkDeviceSize offset,
|
||||||
|
VkDeviceSize size,
|
||||||
|
const void* data);
|
||||||
|
|
||||||
void Tick(Serial completedSerial);
|
void Tick(Serial completedSerial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device* mDevice = nullptr;
|
Device* mDevice = nullptr;
|
||||||
SerialQueue<VkBuffer> mBuffersToDelete;
|
SerialQueue<VkBuffer> mBuffersToDelete;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_BUFFERUPLOADER_H_
|
#endif // BACKEND_VULKAN_BUFFERUPLOADER_H_
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -49,10 +48,9 @@ namespace vulkan {
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
Buffer::Buffer(BufferBuilder* builder)
|
Buffer::Buffer(BufferBuilder* builder) : BufferBase(builder) {
|
||||||
: BufferBase(builder) {
|
|
||||||
Device* device = ToBackend(GetDevice());
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
VkBufferCreateInfo createInfo;
|
VkBufferCreateInfo createInfo;
|
||||||
@ -65,19 +63,24 @@ namespace vulkan {
|
|||||||
createInfo.queueFamilyIndexCount = 0;
|
createInfo.queueFamilyIndexCount = 0;
|
||||||
createInfo.pQueueFamilyIndices = 0;
|
createInfo.pQueueFamilyIndices = 0;
|
||||||
|
|
||||||
if (device->fn.CreateBuffer(device->GetVkDevice(), &createInfo, nullptr, &mHandle) != VK_SUCCESS) {
|
if (device->fn.CreateBuffer(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
|
||||||
|
VK_SUCCESS) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkMemoryRequirements requirements;
|
VkMemoryRequirements requirements;
|
||||||
device->fn.GetBufferMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
|
device->fn.GetBufferMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
|
||||||
|
|
||||||
bool requestMappable = (GetAllowedUsage() & (nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::MapWrite)) != 0;
|
bool requestMappable =
|
||||||
if (!device->GetMemoryAllocator()->Allocate(requirements, requestMappable, &mMemoryAllocation)) {
|
(GetAllowedUsage() & (nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::MapWrite)) !=
|
||||||
|
0;
|
||||||
|
if (!device->GetMemoryAllocator()->Allocate(requirements, requestMappable,
|
||||||
|
&mMemoryAllocation)) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->fn.BindBufferMemory(device->GetVkDevice(), mHandle, mMemoryAllocation.GetMemory(),
|
if (device->fn.BindBufferMemory(device->GetVkDevice(), mHandle,
|
||||||
|
mMemoryAllocation.GetMemory(),
|
||||||
mMemoryAllocation.GetMemoryOffset()) != VK_SUCCESS) {
|
mMemoryAllocation.GetMemoryOffset()) != VK_SUCCESS) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
@ -118,8 +121,7 @@ namespace vulkan {
|
|||||||
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit, nxt::BufferUsageBit) {
|
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit, nxt::BufferUsageBit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MapReadRequestTracker::MapReadRequestTracker(Device* device)
|
MapReadRequestTracker::MapReadRequestTracker(Device* device) : mDevice(device) {
|
||||||
: mDevice(device) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapReadRequestTracker::~MapReadRequestTracker() {
|
MapReadRequestTracker::~MapReadRequestTracker() {
|
||||||
@ -142,5 +144,4 @@ namespace vulkan {
|
|||||||
mInflightRequests.ClearUpTo(finishedSerial);
|
mInflightRequests.ClearUpTo(finishedSerial);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
@ -17,52 +17,51 @@
|
|||||||
|
|
||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
|
|
||||||
#include "backend/vulkan/vulkan_platform.h"
|
|
||||||
#include "backend/vulkan/MemoryAllocator.h"
|
#include "backend/vulkan/MemoryAllocator.h"
|
||||||
|
#include "backend/vulkan/vulkan_platform.h"
|
||||||
#include "common/SerialQueue.h"
|
#include "common/SerialQueue.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
|
||||||
class Buffer : public BufferBase {
|
class Buffer : public BufferBase {
|
||||||
public:
|
public:
|
||||||
Buffer(BufferBuilder* builder);
|
Buffer(BufferBuilder* builder);
|
||||||
~Buffer();
|
~Buffer();
|
||||||
|
|
||||||
void OnMapReadCommandSerialFinished(uint32_t mapSerial, const void* data);
|
void OnMapReadCommandSerialFinished(uint32_t mapSerial, const void* data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
|
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
|
||||||
void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
|
void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) override;
|
void TransitionUsageImpl(nxt::BufferUsageBit currentUsage,
|
||||||
|
nxt::BufferUsageBit targetUsage) override;
|
||||||
|
|
||||||
VkBuffer mHandle = VK_NULL_HANDLE;
|
VkBuffer mHandle = VK_NULL_HANDLE;
|
||||||
DeviceMemoryAllocation mMemoryAllocation;
|
DeviceMemoryAllocation mMemoryAllocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapReadRequestTracker {
|
class MapReadRequestTracker {
|
||||||
public:
|
public:
|
||||||
MapReadRequestTracker(Device* device);
|
MapReadRequestTracker(Device* device);
|
||||||
~MapReadRequestTracker();
|
~MapReadRequestTracker();
|
||||||
|
|
||||||
void Track(Buffer* buffer, uint32_t mapSerial, const void* data);
|
void Track(Buffer* buffer, uint32_t mapSerial, const void* data);
|
||||||
void Tick(Serial finishedSerial);
|
void Tick(Serial finishedSerial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device* mDevice;
|
Device* mDevice;
|
||||||
|
|
||||||
struct Request {
|
struct Request {
|
||||||
Ref<Buffer> buffer;
|
Ref<Buffer> buffer;
|
||||||
uint32_t mapSerial;
|
uint32_t mapSerial;
|
||||||
const void* data;
|
const void* data;
|
||||||
};
|
};
|
||||||
SerialQueue<Request> mInflightRequests;
|
SerialQueue<Request> mInflightRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_BUFFERVK_H_
|
#endif // BACKEND_VULKAN_BUFFERVK_H_
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
#include "backend/vulkan/MemoryAllocator.h"
|
#include "backend/vulkan/MemoryAllocator.h"
|
||||||
#include "backend/vulkan/VulkanBackend.h"
|
#include "backend/vulkan/VulkanBackend.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
DeviceMemoryAllocation::~DeviceMemoryAllocation() {
|
DeviceMemoryAllocation::~DeviceMemoryAllocation() {
|
||||||
ASSERT(mMemory == VK_NULL_HANDLE);
|
ASSERT(mMemory == VK_NULL_HANDLE);
|
||||||
@ -34,15 +33,16 @@ namespace vulkan {
|
|||||||
return mMappedPointer;
|
return mMappedPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryAllocator::MemoryAllocator(Device* device)
|
MemoryAllocator::MemoryAllocator(Device* device) : mDevice(device) {
|
||||||
:mDevice(device) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryAllocator::~MemoryAllocator() {
|
MemoryAllocator::~MemoryAllocator() {
|
||||||
ASSERT(mReleasedMemory.Empty());
|
ASSERT(mReleasedMemory.Empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryAllocator::Allocate(VkMemoryRequirements requirements, bool mappable, DeviceMemoryAllocation* allocation) {
|
bool MemoryAllocator::Allocate(VkMemoryRequirements requirements,
|
||||||
|
bool mappable,
|
||||||
|
DeviceMemoryAllocation* allocation) {
|
||||||
const VulkanDeviceInfo& info = mDevice->GetDeviceInfo();
|
const VulkanDeviceInfo& info = mDevice->GetDeviceInfo();
|
||||||
|
|
||||||
// Find a suitable memory type for this allocation
|
// Find a suitable memory type for this allocation
|
||||||
@ -54,7 +54,8 @@ namespace vulkan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mappable resource must be host visible
|
// Mappable resource must be host visible
|
||||||
if (mappable && (info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
|
if (mappable &&
|
||||||
|
(info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,16 +67,20 @@ namespace vulkan {
|
|||||||
|
|
||||||
// For non-mappable resources, favor device local memory.
|
// For non-mappable resources, favor device local memory.
|
||||||
if (!mappable) {
|
if (!mappable) {
|
||||||
if ((info.memoryTypes[bestType].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0 &&
|
if ((info.memoryTypes[bestType].propertyFlags &
|
||||||
(info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0) {
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0 &&
|
||||||
|
(info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) !=
|
||||||
|
0) {
|
||||||
bestType = static_cast<int>(i);
|
bestType = static_cast<int>(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All things equal favor the memory in the biggest heap
|
// All things equal favor the memory in the biggest heap
|
||||||
VkDeviceSize bestTypeHeapSize = info.memoryHeaps[info.memoryTypes[bestType].heapIndex].size;
|
VkDeviceSize bestTypeHeapSize =
|
||||||
VkDeviceSize candidateHeapSize = info.memoryHeaps[info.memoryTypes[bestType].heapIndex].size;
|
info.memoryHeaps[info.memoryTypes[bestType].heapIndex].size;
|
||||||
|
VkDeviceSize candidateHeapSize =
|
||||||
|
info.memoryHeaps[info.memoryTypes[bestType].heapIndex].size;
|
||||||
if (candidateHeapSize > bestTypeHeapSize) {
|
if (candidateHeapSize > bestTypeHeapSize) {
|
||||||
bestType = static_cast<int>(i);
|
bestType = static_cast<int>(i);
|
||||||
continue;
|
continue;
|
||||||
@ -95,14 +100,15 @@ namespace vulkan {
|
|||||||
allocateInfo.memoryTypeIndex = static_cast<uint32_t>(bestType);
|
allocateInfo.memoryTypeIndex = static_cast<uint32_t>(bestType);
|
||||||
|
|
||||||
VkDeviceMemory allocatedMemory = VK_NULL_HANDLE;
|
VkDeviceMemory allocatedMemory = VK_NULL_HANDLE;
|
||||||
if (mDevice->fn.AllocateMemory(mDevice->GetVkDevice(), &allocateInfo, nullptr, &allocatedMemory) != VK_SUCCESS) {
|
if (mDevice->fn.AllocateMemory(mDevice->GetVkDevice(), &allocateInfo, nullptr,
|
||||||
|
&allocatedMemory) != VK_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* mappedPointer = nullptr;
|
void* mappedPointer = nullptr;
|
||||||
if (mappable) {
|
if (mappable) {
|
||||||
if (mDevice->fn.MapMemory(mDevice->GetVkDevice(), allocatedMemory, 0, requirements.size, 0,
|
if (mDevice->fn.MapMemory(mDevice->GetVkDevice(), allocatedMemory, 0, requirements.size,
|
||||||
&mappedPointer) != VK_SUCCESS) {
|
0, &mappedPointer) != VK_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,5 +133,4 @@ namespace vulkan {
|
|||||||
}
|
}
|
||||||
mReleasedMemory.ClearUpTo(finishedSerial);
|
mReleasedMemory.ClearUpTo(finishedSerial);
|
||||||
}
|
}
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
@ -18,42 +18,42 @@
|
|||||||
#include "backend/vulkan/vulkan_platform.h"
|
#include "backend/vulkan/vulkan_platform.h"
|
||||||
#include "common/SerialQueue.h"
|
#include "common/SerialQueue.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
class MemoryAllocator;
|
class MemoryAllocator;
|
||||||
|
|
||||||
class DeviceMemoryAllocation {
|
class DeviceMemoryAllocation {
|
||||||
public:
|
public:
|
||||||
~DeviceMemoryAllocation();
|
~DeviceMemoryAllocation();
|
||||||
VkDeviceMemory GetMemory() const;
|
VkDeviceMemory GetMemory() const;
|
||||||
size_t GetMemoryOffset() const;
|
size_t GetMemoryOffset() const;
|
||||||
uint8_t* GetMappedPointer() const;
|
uint8_t* GetMappedPointer() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MemoryAllocator;
|
friend class MemoryAllocator;
|
||||||
VkDeviceMemory mMemory = VK_NULL_HANDLE;
|
VkDeviceMemory mMemory = VK_NULL_HANDLE;
|
||||||
size_t mOffset = 0;
|
size_t mOffset = 0;
|
||||||
uint8_t* mMappedPointer = nullptr;
|
uint8_t* mMappedPointer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MemoryAllocator {
|
class MemoryAllocator {
|
||||||
public:
|
public:
|
||||||
MemoryAllocator(Device* device);
|
MemoryAllocator(Device* device);
|
||||||
~MemoryAllocator();
|
~MemoryAllocator();
|
||||||
|
|
||||||
bool Allocate(VkMemoryRequirements requirements, bool mappable, DeviceMemoryAllocation* allocation);
|
bool Allocate(VkMemoryRequirements requirements,
|
||||||
void Free(DeviceMemoryAllocation* allocation);
|
bool mappable,
|
||||||
|
DeviceMemoryAllocation* allocation);
|
||||||
|
void Free(DeviceMemoryAllocation* allocation);
|
||||||
|
|
||||||
void Tick(Serial finishedSerial);
|
void Tick(Serial finishedSerial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device* mDevice = nullptr;
|
Device* mDevice = nullptr;
|
||||||
SerialQueue<VkDeviceMemory> mReleasedMemory;
|
SerialQueue<VkDeviceMemory> mReleasedMemory;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_MEMORYALLOCATOR_H_
|
#endif // BACKEND_VULKAN_MEMORYALLOCATOR_H_
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#include "backend/vulkan/VulkanBackend.h"
|
#include "backend/vulkan/VulkanBackend.h"
|
||||||
|
|
||||||
#include "backend/Commands.h"
|
#include "backend/Commands.h"
|
||||||
#include "backend/vulkan/BufferVk.h"
|
|
||||||
#include "backend/vulkan/BufferUploader.h"
|
#include "backend/vulkan/BufferUploader.h"
|
||||||
|
#include "backend/vulkan/BufferVk.h"
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
|
||||||
#include <spirv-cross/spirv_cross.hpp>
|
#include <spirv-cross/spirv_cross.hpp>
|
||||||
@ -24,15 +24,14 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if NXT_PLATFORM_LINUX
|
#if NXT_PLATFORM_LINUX
|
||||||
const char kVulkanLibName[] = "libvulkan.so.1";
|
const char kVulkanLibName[] = "libvulkan.so.1";
|
||||||
#elif NXT_PLATFORM_WINDOWS
|
#elif NXT_PLATFORM_WINDOWS
|
||||||
const char kVulkanLibName[] = "vulkan-1.dll";
|
const char kVulkanLibName[] = "vulkan-1.dll";
|
||||||
#else
|
#else
|
||||||
#error "Unimplemented Vulkan backend platform"
|
# error "Unimplemented Vulkan backend platform"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
nxtProcTable GetNonValidatingProcs();
|
nxtProcTable GetNonValidatingProcs();
|
||||||
nxtProcTable GetValidatingProcs();
|
nxtProcTable GetValidatingProcs();
|
||||||
@ -330,16 +329,16 @@ namespace vulkan {
|
|||||||
std::vector<const char*> layersToRequest;
|
std::vector<const char*> layersToRequest;
|
||||||
std::vector<const char*> extensionsToRequest;
|
std::vector<const char*> extensionsToRequest;
|
||||||
|
|
||||||
#if defined(NXT_ENABLE_ASSERTS)
|
#if defined(NXT_ENABLE_ASSERTS)
|
||||||
if (mGlobalInfo.standardValidation) {
|
if (mGlobalInfo.standardValidation) {
|
||||||
layersToRequest.push_back(kLayerNameLunargStandardValidation);
|
layersToRequest.push_back(kLayerNameLunargStandardValidation);
|
||||||
usedKnobs->standardValidation = true;
|
usedKnobs->standardValidation = true;
|
||||||
}
|
}
|
||||||
if (mGlobalInfo.debugReport) {
|
if (mGlobalInfo.debugReport) {
|
||||||
extensionsToRequest.push_back(kExtensionNameExtDebugReport);
|
extensionsToRequest.push_back(kExtensionNameExtDebugReport);
|
||||||
usedKnobs->debugReport = true;
|
usedKnobs->debugReport = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VkApplicationInfo appInfo;
|
VkApplicationInfo appInfo;
|
||||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
@ -380,10 +379,12 @@ namespace vulkan {
|
|||||||
|
|
||||||
// Find a universal queue family
|
// Find a universal queue family
|
||||||
{
|
{
|
||||||
constexpr uint32_t kUniversalFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
|
constexpr uint32_t kUniversalFlags =
|
||||||
|
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
|
||||||
int universalQueueFamily = -1;
|
int universalQueueFamily = -1;
|
||||||
for (unsigned int i = 0; i < mDeviceInfo.queueFamilies.size(); ++i) {
|
for (unsigned int i = 0; i < mDeviceInfo.queueFamilies.size(); ++i) {
|
||||||
if ((mDeviceInfo.queueFamilies[i].queueFlags & kUniversalFlags) == kUniversalFlags) {
|
if ((mDeviceInfo.queueFamilies[i].queueFlags & kUniversalFlags) ==
|
||||||
|
kUniversalFlags) {
|
||||||
universalQueueFamily = i;
|
universalQueueFamily = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -439,7 +440,8 @@ namespace vulkan {
|
|||||||
createInfo.pfnCallback = Device::OnDebugReportCallback;
|
createInfo.pfnCallback = Device::OnDebugReportCallback;
|
||||||
createInfo.pUserData = this;
|
createInfo.pUserData = this;
|
||||||
|
|
||||||
if (fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr, &mDebugReportCallback) != VK_SUCCESS) {
|
if (fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr,
|
||||||
|
&mDebugReportCallback) != VK_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +538,8 @@ namespace vulkan {
|
|||||||
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
allocateInfo.commandBufferCount = 1;
|
allocateInfo.commandBufferCount = 1;
|
||||||
|
|
||||||
if (fn.AllocateCommandBuffers(mVkDevice, &allocateInfo, &commands.commandBuffer) != VK_SUCCESS) {
|
if (fn.AllocateCommandBuffers(mVkDevice, &allocateInfo, &commands.commandBuffer) !=
|
||||||
|
VK_SUCCESS) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,8 +568,7 @@ namespace vulkan {
|
|||||||
|
|
||||||
// Queue
|
// Queue
|
||||||
|
|
||||||
Queue::Queue(QueueBuilder* builder)
|
Queue::Queue(QueueBuilder* builder) : QueueBase(builder) {
|
||||||
: QueueBase(builder) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue::~Queue() {
|
Queue::~Queue() {
|
||||||
@ -577,8 +579,7 @@ namespace vulkan {
|
|||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
|
|
||||||
Texture::Texture(TextureBuilder* builder)
|
Texture::Texture(TextureBuilder* builder) : TextureBase(builder) {
|
||||||
: TextureBase(builder) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
@ -589,8 +590,7 @@ namespace vulkan {
|
|||||||
|
|
||||||
// SwapChain
|
// SwapChain
|
||||||
|
|
||||||
SwapChain::SwapChain(SwapChainBuilder* builder)
|
SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) {
|
||||||
: SwapChainBase(builder) {
|
|
||||||
const auto& im = GetImplementation();
|
const auto& im = GetImplementation();
|
||||||
im.Init(im.userData, nullptr);
|
im.Init(im.userData, nullptr);
|
||||||
}
|
}
|
||||||
@ -601,5 +601,4 @@ namespace vulkan {
|
|||||||
TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) {
|
TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) {
|
||||||
return GetDevice()->CreateTexture(builder);
|
return GetDevice()->CreateTexture(builder);
|
||||||
}
|
}
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
@ -17,15 +17,13 @@
|
|||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
#include "backend/vulkan/VulkanFunctions.h"
|
|
||||||
#include "backend/vulkan/VulkanInfo.h"
|
|
||||||
#include "backend/BindGroup.h"
|
#include "backend/BindGroup.h"
|
||||||
#include "backend/BindGroupLayout.h"
|
#include "backend/BindGroupLayout.h"
|
||||||
#include "backend/BlendState.h"
|
#include "backend/BlendState.h"
|
||||||
#include "backend/Device.h"
|
|
||||||
#include "backend/CommandBuffer.h"
|
#include "backend/CommandBuffer.h"
|
||||||
#include "backend/ComputePipeline.h"
|
#include "backend/ComputePipeline.h"
|
||||||
#include "backend/DepthStencilState.h"
|
#include "backend/DepthStencilState.h"
|
||||||
|
#include "backend/Device.h"
|
||||||
#include "backend/Framebuffer.h"
|
#include "backend/Framebuffer.h"
|
||||||
#include "backend/InputState.h"
|
#include "backend/InputState.h"
|
||||||
#include "backend/PipelineLayout.h"
|
#include "backend/PipelineLayout.h"
|
||||||
@ -37,14 +35,15 @@
|
|||||||
#include "backend/SwapChain.h"
|
#include "backend/SwapChain.h"
|
||||||
#include "backend/Texture.h"
|
#include "backend/Texture.h"
|
||||||
#include "backend/ToBackend.h"
|
#include "backend/ToBackend.h"
|
||||||
|
#include "backend/vulkan/VulkanFunctions.h"
|
||||||
|
#include "backend/vulkan/VulkanInfo.h"
|
||||||
#include "common/DynamicLib.h"
|
#include "common/DynamicLib.h"
|
||||||
#include "common/Serial.h"
|
#include "common/Serial.h"
|
||||||
#include "common/SerialQueue.h"
|
#include "common/SerialQueue.h"
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
using BindGroup = BindGroupBase;
|
using BindGroup = BindGroupBase;
|
||||||
using BindGroupLayout = BindGroupLayoutBase;
|
using BindGroupLayout = BindGroupLayoutBase;
|
||||||
@ -94,143 +93,143 @@ namespace vulkan {
|
|||||||
using TextureViewType = TextureView;
|
using TextureViewType = TextureView;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
auto ToBackend(T&& common) -> decltype(ToBackendBase<VulkanBackendTraits>(common)) {
|
auto ToBackend(T&& common) -> decltype(ToBackendBase<VulkanBackendTraits>(common)) {
|
||||||
return ToBackendBase<VulkanBackendTraits>(common);
|
return ToBackendBase<VulkanBackendTraits>(common);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Device : public DeviceBase {
|
class Device : public DeviceBase {
|
||||||
public:
|
public:
|
||||||
Device();
|
Device();
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
||||||
BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override;
|
BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override;
|
||||||
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
||||||
BufferBase* CreateBuffer(BufferBuilder* builder) override;
|
BufferBase* CreateBuffer(BufferBuilder* builder) override;
|
||||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||||
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
|
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
|
||||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
||||||
QueueBase* CreateQueue(QueueBuilder* builder) override;
|
QueueBase* CreateQueue(QueueBuilder* builder) override;
|
||||||
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
|
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
|
||||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||||
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
|
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
|
||||||
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
|
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
|
||||||
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
||||||
TextureBase* CreateTexture(TextureBuilder* builder) override;
|
TextureBase* CreateTexture(TextureBuilder* builder) override;
|
||||||
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
|
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
|
||||||
|
|
||||||
void TickImpl() override;
|
void TickImpl() override;
|
||||||
|
|
||||||
const VulkanDeviceInfo& GetDeviceInfo() const;
|
const VulkanDeviceInfo& GetDeviceInfo() const;
|
||||||
MapReadRequestTracker* GetMapReadRequestTracker() const;
|
MapReadRequestTracker* GetMapReadRequestTracker() const;
|
||||||
MemoryAllocator* GetMemoryAllocator() const;
|
MemoryAllocator* GetMemoryAllocator() const;
|
||||||
BufferUploader* GetBufferUploader() const;
|
BufferUploader* GetBufferUploader() const;
|
||||||
|
|
||||||
Serial GetSerial() const;
|
Serial GetSerial() const;
|
||||||
|
|
||||||
VkCommandBuffer GetPendingCommandBuffer();
|
VkCommandBuffer GetPendingCommandBuffer();
|
||||||
void SubmitPendingCommands();
|
void SubmitPendingCommands();
|
||||||
|
|
||||||
// Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
|
// Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
|
||||||
const VulkanFunctions fn;
|
const VulkanFunctions fn;
|
||||||
|
|
||||||
VkInstance GetInstance() const;
|
VkInstance GetInstance() const;
|
||||||
VkDevice GetVkDevice() const;
|
VkDevice GetVkDevice() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CreateInstance(VulkanGlobalKnobs* usedKnobs);
|
bool CreateInstance(VulkanGlobalKnobs* usedKnobs);
|
||||||
bool CreateDevice(VulkanDeviceKnobs* usedKnobs);
|
bool CreateDevice(VulkanDeviceKnobs* usedKnobs);
|
||||||
void GatherQueueFromDevice();
|
void GatherQueueFromDevice();
|
||||||
|
|
||||||
bool RegisterDebugReport();
|
bool RegisterDebugReport();
|
||||||
static VkBool32 OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
static VkBool32 OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||||
VkDebugReportObjectTypeEXT objectType,
|
VkDebugReportObjectTypeEXT objectType,
|
||||||
uint64_t object,
|
uint64_t object,
|
||||||
size_t location,
|
size_t location,
|
||||||
int32_t messageCode,
|
int32_t messageCode,
|
||||||
const char* pLayerPrefix,
|
const char* pLayerPrefix,
|
||||||
const char* pMessage,
|
const char* pMessage,
|
||||||
void* pUserdata);
|
void* pUserdata);
|
||||||
|
|
||||||
// To make it easier to use fn it is a public const member. However
|
// To make it easier to use fn it is a public const member. However
|
||||||
// the Device is allowed to mutate them through these private methods.
|
// the Device is allowed to mutate them through these private methods.
|
||||||
VulkanFunctions* GetMutableFunctions();
|
VulkanFunctions* GetMutableFunctions();
|
||||||
|
|
||||||
VulkanGlobalInfo mGlobalInfo;
|
VulkanGlobalInfo mGlobalInfo;
|
||||||
VulkanDeviceInfo mDeviceInfo;
|
VulkanDeviceInfo mDeviceInfo;
|
||||||
|
|
||||||
DynamicLib mVulkanLib;
|
DynamicLib mVulkanLib;
|
||||||
|
|
||||||
VkInstance mInstance = VK_NULL_HANDLE;
|
VkInstance mInstance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
|
||||||
VkDevice mVkDevice = VK_NULL_HANDLE;
|
VkDevice mVkDevice = VK_NULL_HANDLE;
|
||||||
uint32_t mQueueFamily = 0;
|
uint32_t mQueueFamily = 0;
|
||||||
VkQueue mQueue = VK_NULL_HANDLE;
|
VkQueue mQueue = VK_NULL_HANDLE;
|
||||||
VkDebugReportCallbackEXT mDebugReportCallback = VK_NULL_HANDLE;
|
VkDebugReportCallbackEXT mDebugReportCallback = VK_NULL_HANDLE;
|
||||||
|
|
||||||
MapReadRequestTracker* mMapReadRequestTracker = nullptr;
|
MapReadRequestTracker* mMapReadRequestTracker = nullptr;
|
||||||
MemoryAllocator* mMemoryAllocator = nullptr;
|
MemoryAllocator* mMemoryAllocator = nullptr;
|
||||||
BufferUploader* mBufferUploader = nullptr;
|
BufferUploader* mBufferUploader = nullptr;
|
||||||
|
|
||||||
VkFence GetUnusedFence();
|
VkFence GetUnusedFence();
|
||||||
void CheckPassedFences();
|
void CheckPassedFences();
|
||||||
|
|
||||||
// We track which operations are in flight on the GPU with an increasing serial.
|
// We track which operations are in flight on the GPU with an increasing serial.
|
||||||
// This works only because we have a single queue. Each submit to a queue is associated
|
// This works only because we have a single queue. Each submit to a queue is associated
|
||||||
// to a serial and a fence, such that when the fence is "ready" we know the operations
|
// to a serial and a fence, such that when the fence is "ready" we know the operations
|
||||||
// have finished.
|
// have finished.
|
||||||
std::queue<std::pair<VkFence, Serial>> mFencesInFlight;
|
std::queue<std::pair<VkFence, Serial>> mFencesInFlight;
|
||||||
std::vector<VkFence> mUnusedFences;
|
std::vector<VkFence> mUnusedFences;
|
||||||
Serial mNextSerial = 1;
|
Serial mNextSerial = 1;
|
||||||
Serial mCompletedSerial = 0;
|
Serial mCompletedSerial = 0;
|
||||||
|
|
||||||
struct CommandPoolAndBuffer {
|
struct CommandPoolAndBuffer {
|
||||||
VkCommandPool pool = VK_NULL_HANDLE;
|
VkCommandPool pool = VK_NULL_HANDLE;
|
||||||
VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
|
VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
|
|
||||||
CommandPoolAndBuffer GetUnusedCommands();
|
CommandPoolAndBuffer GetUnusedCommands();
|
||||||
void RecycleCompletedCommands();
|
void RecycleCompletedCommands();
|
||||||
void FreeCommands(CommandPoolAndBuffer* commands);
|
void FreeCommands(CommandPoolAndBuffer* commands);
|
||||||
|
|
||||||
SerialQueue<CommandPoolAndBuffer> mCommandsInFlight;
|
SerialQueue<CommandPoolAndBuffer> mCommandsInFlight;
|
||||||
std::vector<CommandPoolAndBuffer> mUnusedCommands;
|
std::vector<CommandPoolAndBuffer> mUnusedCommands;
|
||||||
CommandPoolAndBuffer mPendingCommands;
|
CommandPoolAndBuffer mPendingCommands;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Queue : public QueueBase {
|
class Queue : public QueueBase {
|
||||||
public:
|
public:
|
||||||
Queue(QueueBuilder* builder);
|
Queue(QueueBuilder* builder);
|
||||||
~Queue();
|
~Queue();
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void Submit(uint32_t numCommands, CommandBuffer* const * commands);
|
void Submit(uint32_t numCommands, CommandBuffer* const* commands);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture : public TextureBase {
|
class Texture : public TextureBase {
|
||||||
public:
|
public:
|
||||||
Texture(TextureBuilder* builder);
|
Texture(TextureBuilder* builder);
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void TransitionUsageImpl(nxt::TextureUsageBit currentUsage, nxt::TextureUsageBit targetUsage) override;
|
void TransitionUsageImpl(nxt::TextureUsageBit currentUsage,
|
||||||
|
nxt::TextureUsageBit targetUsage) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SwapChain : public SwapChainBase {
|
class SwapChain : public SwapChainBase {
|
||||||
public:
|
public:
|
||||||
SwapChain(SwapChainBuilder* builder);
|
SwapChain(SwapChainBuilder* builder);
|
||||||
~SwapChain();
|
~SwapChain();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
|
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_VULKANBACKEND_H_
|
#endif // BACKEND_VULKAN_VULKANBACKEND_H_
|
||||||
|
@ -17,14 +17,13 @@
|
|||||||
#include "backend/vulkan/VulkanInfo.h"
|
#include "backend/vulkan/VulkanInfo.h"
|
||||||
#include "common/DynamicLib.h"
|
#include "common/DynamicLib.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
#define GET_GLOBAL_PROC(name) \
|
#define GET_GLOBAL_PROC(name) \
|
||||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \
|
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \
|
||||||
if (name == nullptr) { \
|
if (name == nullptr) { \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
|
bool VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
|
||||||
if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) {
|
if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) {
|
||||||
@ -38,14 +37,16 @@ namespace vulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_INSTANCE_PROC(name) \
|
#define GET_INSTANCE_PROC(name) \
|
||||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
|
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
|
||||||
if (name == nullptr) { \
|
if (name == nullptr) { \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanFunctions::LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedKnobs) {
|
bool VulkanFunctions::LoadInstanceProcs(VkInstance instance,
|
||||||
// Load this proc first so that we can destroy the instance even if some other GET_INSTANCE_PROC fails
|
const VulkanGlobalKnobs& usedKnobs) {
|
||||||
|
// Load this proc first so that we can destroy the instance even if some other
|
||||||
|
// GET_INSTANCE_PROC fails
|
||||||
GET_INSTANCE_PROC(DestroyInstance);
|
GET_INSTANCE_PROC(DestroyInstance);
|
||||||
|
|
||||||
GET_INSTANCE_PROC(CreateDevice);
|
GET_INSTANCE_PROC(CreateDevice);
|
||||||
@ -79,11 +80,11 @@ namespace vulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_DEVICE_PROC(name) \
|
#define GET_DEVICE_PROC(name) \
|
||||||
name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
|
name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
|
||||||
if (name == nullptr) { \
|
if (name == nullptr) { \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanFunctions::LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs) {
|
bool VulkanFunctions::LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs) {
|
||||||
GET_DEVICE_PROC(AllocateCommandBuffers);
|
GET_DEVICE_PROC(AllocateCommandBuffers);
|
||||||
@ -217,5 +218,4 @@ namespace vulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
class DynamicLib;
|
class DynamicLib;
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
struct VulkanGlobalKnobs;
|
struct VulkanGlobalKnobs;
|
||||||
struct VulkanDeviceKnobs;
|
struct VulkanDeviceKnobs;
|
||||||
@ -54,11 +53,14 @@ namespace vulkan {
|
|||||||
PFN_vkGetDeviceProcAddr GetDeviceProcAddr = nullptr;
|
PFN_vkGetDeviceProcAddr GetDeviceProcAddr = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures = nullptr;
|
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties = nullptr;
|
PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties = nullptr;
|
PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties =
|
||||||
|
nullptr;
|
||||||
PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties = nullptr;
|
PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties = nullptr;
|
PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties = nullptr;
|
PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties =
|
||||||
PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties = nullptr;
|
nullptr;
|
||||||
|
PFN_vkGetPhysicalDeviceSparseImageFormatProperties
|
||||||
|
GetPhysicalDeviceSparseImageFormatProperties = nullptr;
|
||||||
// Not technically an instance proc but we want to be able to use it as soon as the
|
// Not technically an instance proc but we want to be able to use it as soon as the
|
||||||
// device is created.
|
// device is created.
|
||||||
PFN_vkDestroyDevice DestroyDevice = nullptr;
|
PFN_vkDestroyDevice DestroyDevice = nullptr;
|
||||||
@ -71,9 +73,11 @@ namespace vulkan {
|
|||||||
// VK_KHR_surface
|
// VK_KHR_surface
|
||||||
PFN_vkDestroySurfaceKHR DestroySurfaceKHR = nullptr;
|
PFN_vkDestroySurfaceKHR DestroySurfaceKHR = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR = nullptr;
|
PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
|
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR =
|
||||||
|
nullptr;
|
||||||
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR = nullptr;
|
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR = nullptr;
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR =
|
||||||
|
nullptr;
|
||||||
|
|
||||||
// ---------- Device procs
|
// ---------- Device procs
|
||||||
|
|
||||||
@ -206,7 +210,6 @@ namespace vulkan {
|
|||||||
PFN_vkQueuePresentKHR QueuePresentKHR = nullptr;
|
PFN_vkQueuePresentKHR QueuePresentKHR = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_VULKANFUNCTIONS_H_
|
#endif // BACKEND_VULKAN_VULKANFUNCTIONS_H_
|
||||||
|
@ -26,10 +26,9 @@ namespace {
|
|||||||
bool IsExtensionName(const VkExtensionProperties& extension, const char* name) {
|
bool IsExtensionName(const VkExtensionProperties& extension, const char* name) {
|
||||||
return strncmp(extension.extensionName, name, VK_MAX_EXTENSION_NAME_SIZE) == 0;
|
return strncmp(extension.extensionName, name, VK_MAX_EXTENSION_NAME_SIZE) == 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
const char kLayerNameLunargStandardValidation[] = "VK_LAYER_LUNARG_standard_validation";
|
const char kLayerNameLunargStandardValidation[] = "VK_LAYER_LUNARG_standard_validation";
|
||||||
|
|
||||||
@ -65,13 +64,15 @@ namespace vulkan {
|
|||||||
// Gather the info about the instance extensions
|
// Gather the info about the instance extensions
|
||||||
{
|
{
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
VkResult result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
VkResult result =
|
||||||
|
device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
||||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->extensions.resize(count);
|
info->extensions.resize(count);
|
||||||
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, info->extensions.data());
|
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count,
|
||||||
|
info->extensions.data());
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -109,7 +110,9 @@ namespace vulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GatherDeviceInfo(const Device& device, VkPhysicalDevice physicalDevice, VulkanDeviceInfo* info) {
|
bool GatherDeviceInfo(const Device& device,
|
||||||
|
VkPhysicalDevice physicalDevice,
|
||||||
|
VulkanDeviceInfo* info) {
|
||||||
// Gather general info about the device
|
// Gather general info about the device
|
||||||
device.fn.GetPhysicalDeviceProperties(physicalDevice, &info->properties);
|
device.fn.GetPhysicalDeviceProperties(physicalDevice, &info->properties);
|
||||||
device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info->features);
|
device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info->features);
|
||||||
@ -119,8 +122,10 @@ namespace vulkan {
|
|||||||
VkPhysicalDeviceMemoryProperties memory;
|
VkPhysicalDeviceMemoryProperties memory;
|
||||||
device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
|
device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
|
||||||
|
|
||||||
info->memoryTypes.assign(memory.memoryTypes, memory.memoryTypes + memory.memoryTypeCount);
|
info->memoryTypes.assign(memory.memoryTypes,
|
||||||
info->memoryHeaps.assign(memory.memoryHeaps, memory.memoryHeaps + memory.memoryHeapCount);
|
memory.memoryTypes + memory.memoryTypeCount);
|
||||||
|
info->memoryHeaps.assign(memory.memoryHeaps,
|
||||||
|
memory.memoryHeaps + memory.memoryHeapCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather info about device queue families
|
// Gather info about device queue families
|
||||||
@ -129,19 +134,22 @@ namespace vulkan {
|
|||||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
|
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
|
||||||
|
|
||||||
info->queueFamilies.resize(count);
|
info->queueFamilies.resize(count);
|
||||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, info->queueFamilies.data());
|
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count,
|
||||||
|
info->queueFamilies.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather the info about the device layers
|
// Gather the info about the device layers
|
||||||
{
|
{
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
VkResult result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
|
VkResult result =
|
||||||
|
device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
|
||||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->layers.resize(count);
|
info->layers.resize(count);
|
||||||
result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, info->layers.data());
|
result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count,
|
||||||
|
info->layers.data());
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -150,13 +158,15 @@ namespace vulkan {
|
|||||||
// Gather the info about the device extensions
|
// Gather the info about the device extensions
|
||||||
{
|
{
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, nullptr);
|
VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
|
||||||
|
&count, nullptr);
|
||||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->extensions.resize(count);
|
info->extensions.resize(count);
|
||||||
result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, info->extensions.data());
|
result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count,
|
||||||
|
info->extensions.data());
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -173,5 +183,4 @@ namespace vulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}} // namespace backend::vulkan
|
||||||
}
|
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend { namespace vulkan {
|
||||||
namespace vulkan {
|
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
|
||||||
@ -68,8 +67,9 @@ namespace vulkan {
|
|||||||
|
|
||||||
bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info);
|
bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info);
|
||||||
bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices);
|
bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices);
|
||||||
bool GatherDeviceInfo(const Device& device, VkPhysicalDevice physicalDevice, VulkanDeviceInfo* info);
|
bool GatherDeviceInfo(const Device& device,
|
||||||
}
|
VkPhysicalDevice physicalDevice,
|
||||||
}
|
VulkanDeviceInfo* info);
|
||||||
|
}} // namespace backend::vulkan
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_VULKANINFO_H_
|
#endif // BACKEND_VULKAN_VULKANINFO_H_
|
||||||
|
@ -17,4 +17,4 @@
|
|||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#endif // BACKEND_VULKAN_VULKANPLATFORM_H_
|
#endif // BACKEND_VULKAN_VULKANPLATFORM_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user