mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-06 05:06:07 +00:00
Vulkan: Implement buffer transitions
This commit is contained in:
parent
77a1d908b6
commit
160abad592
@ -41,7 +41,7 @@ namespace backend {
|
|||||||
return new BufferViewBuilder(mDevice, this);
|
return new BufferViewBuilder(mDevice, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceBase* BufferBase::GetDevice() {
|
DeviceBase* BufferBase::GetDevice() const {
|
||||||
return mDevice;
|
return mDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace backend {
|
|||||||
bool HasFrozenUsage(nxt::BufferUsageBit usage) const;
|
bool HasFrozenUsage(nxt::BufferUsageBit usage) const;
|
||||||
void UpdateUsageInternal(nxt::BufferUsageBit usage);
|
void UpdateUsageInternal(nxt::BufferUsageBit usage);
|
||||||
|
|
||||||
DeviceBase* GetDevice();
|
DeviceBase* GetDevice() const;
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
BufferViewBuilder* CreateBufferViewBuilder();
|
BufferViewBuilder* CreateBufferViewBuilder();
|
||||||
|
@ -49,6 +49,58 @@ namespace backend { namespace vulkan {
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPipelineStageFlags VulkanPipelineStage(nxt::BufferUsageBit usage) {
|
||||||
|
VkPipelineStageFlags flags = 0;
|
||||||
|
|
||||||
|
if (usage & (nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::MapWrite)) {
|
||||||
|
flags |= VK_PIPELINE_STAGE_HOST_BIT;
|
||||||
|
}
|
||||||
|
if (usage & (nxt::BufferUsageBit::TransferSrc | nxt::BufferUsageBit::TransferDst)) {
|
||||||
|
flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
|
}
|
||||||
|
if (usage & (nxt::BufferUsageBit::Index | nxt::BufferUsageBit::Vertex)) {
|
||||||
|
flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||||
|
}
|
||||||
|
if (usage & (nxt::BufferUsageBit::Uniform | nxt::BufferUsageBit::Storage)) {
|
||||||
|
flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkAccessFlags VulkanAccessFlags(nxt::BufferUsageBit usage) {
|
||||||
|
VkAccessFlags flags = 0;
|
||||||
|
|
||||||
|
if (usage & nxt::BufferUsageBit::MapRead) {
|
||||||
|
flags |= VK_ACCESS_HOST_READ_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::MapWrite) {
|
||||||
|
flags |= VK_ACCESS_HOST_WRITE_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::TransferSrc) {
|
||||||
|
flags |= VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::TransferDst) {
|
||||||
|
flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::Index) {
|
||||||
|
flags |= VK_ACCESS_INDEX_READ_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::Vertex) {
|
||||||
|
flags |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::Uniform) {
|
||||||
|
flags |= VK_ACCESS_UNIFORM_READ_BIT;
|
||||||
|
}
|
||||||
|
if (usage & nxt::BufferUsageBit::Storage) {
|
||||||
|
flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Buffer::Buffer(BufferBuilder* builder) : BufferBase(builder) {
|
Buffer::Buffer(BufferBuilder* builder) : BufferBase(builder) {
|
||||||
@ -106,6 +158,28 @@ namespace backend { namespace vulkan {
|
|||||||
return mHandle;
|
return mHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Buffer::RecordBarrier(VkCommandBuffer commands,
|
||||||
|
nxt::BufferUsageBit currentUsage,
|
||||||
|
nxt::BufferUsageBit targetUsage) const {
|
||||||
|
VkPipelineStageFlags srcStages = VulkanPipelineStage(currentUsage);
|
||||||
|
VkPipelineStageFlags dstStages = VulkanPipelineStage(targetUsage);
|
||||||
|
|
||||||
|
VkBufferMemoryBarrier barrier;
|
||||||
|
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||||
|
barrier.pNext = nullptr;
|
||||||
|
barrier.srcAccessMask = VulkanAccessFlags(currentUsage);
|
||||||
|
barrier.dstAccessMask = VulkanAccessFlags(targetUsage);
|
||||||
|
barrier.srcQueueFamilyIndex = 0;
|
||||||
|
barrier.dstQueueFamilyIndex = 0;
|
||||||
|
barrier.buffer = mHandle;
|
||||||
|
barrier.offset = 0;
|
||||||
|
barrier.size = GetSize();
|
||||||
|
|
||||||
|
ToBackend(GetDevice())
|
||||||
|
->fn.CmdPipelineBarrier(commands, srcStages, dstStages, 0, 0, nullptr, 1, &barrier, 0,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
|
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
|
||||||
BufferUploader* uploader = ToBackend(GetDevice())->GetBufferUploader();
|
BufferUploader* uploader = ToBackend(GetDevice())->GetBufferUploader();
|
||||||
uploader->BufferSubData(mHandle, start * sizeof(uint32_t), count * sizeof(uint32_t), data);
|
uploader->BufferSubData(mHandle, start * sizeof(uint32_t), count * sizeof(uint32_t), data);
|
||||||
@ -123,7 +197,10 @@ namespace backend { namespace vulkan {
|
|||||||
// No need to do anything, we keep CPU-visible memory mapped at all time.
|
// No need to do anything, we keep CPU-visible memory mapped at all time.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit, nxt::BufferUsageBit) {
|
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit currentUsage,
|
||||||
|
nxt::BufferUsageBit targetUsage) {
|
||||||
|
VkCommandBuffer commands = ToBackend(GetDevice())->GetPendingCommandBuffer();
|
||||||
|
RecordBarrier(commands, currentUsage, targetUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapReadRequestTracker::MapReadRequestTracker(Device* device) : mDevice(device) {
|
MapReadRequestTracker::MapReadRequestTracker(Device* device) : mDevice(device) {
|
||||||
|
@ -34,6 +34,10 @@ namespace backend { namespace vulkan {
|
|||||||
|
|
||||||
VkBuffer GetHandle() const;
|
VkBuffer GetHandle() const;
|
||||||
|
|
||||||
|
void RecordBarrier(VkCommandBuffer commands,
|
||||||
|
nxt::BufferUsageBit currentUsage,
|
||||||
|
nxt::BufferUsageBit targetUsage) const;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -52,7 +52,12 @@ namespace backend { namespace vulkan {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::TransitionBufferUsage: {
|
case Command::TransitionBufferUsage: {
|
||||||
SkipCommand(&mCommands, type);
|
TransitionBufferUsageCmd* cmd =
|
||||||
|
mCommands.NextCommand<TransitionBufferUsageCmd>();
|
||||||
|
|
||||||
|
Buffer* buffer = ToBackend(cmd->buffer.Get());
|
||||||
|
buffer->RecordBarrier(commands, buffer->GetUsage(), cmd->usage);
|
||||||
|
buffer->UpdateUsageInternal(cmd->usage);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: { UNREACHABLE(); } break;
|
default: { UNREACHABLE(); } break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user