Vulkan: Handle CopyBufferToBuffer commands
This as this is the first command handled by the Vulkan backend, this commit also introduces the b:✌️:CommandBUffer class and implements b:✌️:Queue::Submit. Also enables the BufferSetSubData tests that are now passing on Vulkan even though the buffer transitions are unimplemented.
This commit is contained in:
parent
a9b98af710
commit
77a1d908b6
|
@ -293,6 +293,8 @@ if (NXT_ENABLE_VULKAN)
|
||||||
${VULKAN_DIR}/BufferUploader.h
|
${VULKAN_DIR}/BufferUploader.h
|
||||||
${VULKAN_DIR}/BufferVk.cpp
|
${VULKAN_DIR}/BufferVk.cpp
|
||||||
${VULKAN_DIR}/BufferVk.h
|
${VULKAN_DIR}/BufferVk.h
|
||||||
|
${VULKAN_DIR}/CommandBufferVk.cpp
|
||||||
|
${VULKAN_DIR}/CommandBufferVk.h
|
||||||
${VULKAN_DIR}/FencedDeleter.cpp
|
${VULKAN_DIR}/FencedDeleter.cpp
|
||||||
${VULKAN_DIR}/FencedDeleter.h
|
${VULKAN_DIR}/FencedDeleter.h
|
||||||
${VULKAN_DIR}/MemoryAllocator.cpp
|
${VULKAN_DIR}/MemoryAllocator.cpp
|
||||||
|
|
|
@ -168,6 +168,7 @@ namespace backend {
|
||||||
|
|
||||||
// This needs to be called before the CommandIterator is freed so that the Ref<> present in
|
// This needs to be called before the CommandIterator is freed so that the Ref<> present in
|
||||||
// the commands have a chance to run their destructor and remove internal references.
|
// the commands have a chance to run their destructor and remove internal references.
|
||||||
|
class CommandIterator;
|
||||||
void FreeCommands(CommandIterator* commands);
|
void FreeCommands(CommandIterator* commands);
|
||||||
void SkipCommand(CommandIterator* commands, Command type);
|
void SkipCommand(CommandIterator* commands, Command type);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace backend { namespace d3d12 {
|
||||||
Device* mDevice;
|
Device* mDevice;
|
||||||
CommandIterator mCommands;
|
CommandIterator mCommands;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace backend::d3d12
|
}} // namespace backend::d3d12
|
||||||
|
|
||||||
#endif // BACKEND_D3D12_COMMANDBUFFERD3D12_H_
|
#endif // BACKEND_D3D12_COMMANDBUFFERD3D12_H_
|
||||||
|
|
|
@ -102,6 +102,10 @@ namespace backend { namespace vulkan {
|
||||||
CallMapReadCallback(mapSerial, NXT_BUFFER_MAP_READ_STATUS_SUCCESS, data);
|
CallMapReadCallback(mapSerial, NXT_BUFFER_MAP_READ_STATUS_SUCCESS, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkBuffer Buffer::GetHandle() const {
|
||||||
|
return mHandle;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace backend { namespace vulkan {
|
||||||
|
|
||||||
void OnMapReadCommandSerialFinished(uint32_t mapSerial, const void* data);
|
void OnMapReadCommandSerialFinished(uint32_t mapSerial, const void* data);
|
||||||
|
|
||||||
|
VkBuffer GetHandle() 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;
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright 2017 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/CommandBufferVk.h"
|
||||||
|
|
||||||
|
#include "backend/Commands.h"
|
||||||
|
#include "backend/vulkan/BufferVk.h"
|
||||||
|
#include "backend/vulkan/VulkanBackend.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace backend { namespace vulkan {
|
||||||
|
|
||||||
|
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
|
||||||
|
: CommandBufferBase(builder), mCommands(builder->AcquireCommands()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandBuffer::~CommandBuffer() {
|
||||||
|
FreeCommands(&mCommands);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandBuffer::RecordCommands(VkCommandBuffer commands) {
|
||||||
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
|
Command type;
|
||||||
|
while (mCommands.NextCommandId(&type)) {
|
||||||
|
switch (type) {
|
||||||
|
case Command::CopyBufferToBuffer: {
|
||||||
|
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
|
||||||
|
auto& src = copy->source;
|
||||||
|
auto& dst = copy->destination;
|
||||||
|
|
||||||
|
VkBufferCopy region;
|
||||||
|
region.srcOffset = src.offset;
|
||||||
|
region.dstOffset = dst.offset;
|
||||||
|
region.size = copy->size;
|
||||||
|
|
||||||
|
VkBuffer srcHandle = ToBackend(src.buffer)->GetHandle();
|
||||||
|
VkBuffer dstHandle = ToBackend(dst.buffer)->GetHandle();
|
||||||
|
device->fn.CmdCopyBuffer(commands, srcHandle, dstHandle, 1, ®ion);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::TransitionBufferUsage: {
|
||||||
|
SkipCommand(&mCommands, type);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: { UNREACHABLE(); } break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace backend::vulkan
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2017 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_COMMANDBUFFERVK_H_
|
||||||
|
#define BACKEND_VULKAN_COMMANDBUFFERVK_H_
|
||||||
|
|
||||||
|
#include "backend/CommandBuffer.h"
|
||||||
|
|
||||||
|
#include "backend/vulkan/vulkan_platform.h"
|
||||||
|
|
||||||
|
namespace backend { namespace vulkan {
|
||||||
|
|
||||||
|
class CommandBuffer : public CommandBufferBase {
|
||||||
|
public:
|
||||||
|
CommandBuffer(CommandBufferBuilder* builder);
|
||||||
|
~CommandBuffer();
|
||||||
|
|
||||||
|
void RecordCommands(VkCommandBuffer commands);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CommandIterator mCommands;
|
||||||
|
};
|
||||||
|
|
||||||
|
}} // namespace backend::vulkan
|
||||||
|
|
||||||
|
#endif // BACKEND_VULKAN_COMMANDBUFFERVK_H_
|
|
@ -13,4 +13,5 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "backend/vulkan/BufferVk.h"
|
#include "backend/vulkan/BufferVk.h"
|
||||||
|
#include "backend/vulkan/CommandBufferVk.h"
|
||||||
#include "backend/vulkan/VulkanBackend.h"
|
#include "backend/vulkan/VulkanBackend.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "backend/Commands.h"
|
#include "backend/Commands.h"
|
||||||
#include "backend/vulkan/BufferUploader.h"
|
#include "backend/vulkan/BufferUploader.h"
|
||||||
#include "backend/vulkan/BufferVk.h"
|
#include "backend/vulkan/BufferVk.h"
|
||||||
|
#include "backend/vulkan/CommandBufferVk.h"
|
||||||
#include "backend/vulkan/FencedDeleter.h"
|
#include "backend/vulkan/FencedDeleter.h"
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
|
||||||
|
@ -246,6 +247,11 @@ namespace backend { namespace vulkan {
|
||||||
|
|
||||||
if (mPendingCommands.pool != VK_NULL_HANDLE) {
|
if (mPendingCommands.pool != VK_NULL_HANDLE) {
|
||||||
SubmitPendingCommands();
|
SubmitPendingCommands();
|
||||||
|
} else if (mCompletedSerial == mNextSerial - 1) {
|
||||||
|
// If there's no GPU work in flight we still need to artificially increment the serial
|
||||||
|
// so that CPU operations waiting on GPU completion can know they don't have to wait.
|
||||||
|
mCompletedSerial++;
|
||||||
|
mNextSerial++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +590,15 @@ namespace backend { namespace vulkan {
|
||||||
Queue::~Queue() {
|
Queue::~Queue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Queue::Submit(uint32_t, CommandBuffer* const*) {
|
void Queue::Submit(uint32_t numCommands, CommandBuffer* const* commands) {
|
||||||
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
|
VkCommandBuffer commandBuffer = device->GetPendingCommandBuffer();
|
||||||
|
for (uint32_t i = 0; i < numCommands; ++i) {
|
||||||
|
commands[i]->RecordCommands(commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
device->SubmitPendingCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#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/CommandBuffer.h"
|
|
||||||
#include "backend/ComputePipeline.h"
|
#include "backend/ComputePipeline.h"
|
||||||
#include "backend/DepthStencilState.h"
|
#include "backend/DepthStencilState.h"
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
|
@ -50,7 +49,7 @@ namespace backend { namespace vulkan {
|
||||||
using BlendState = BlendStateBase;
|
using BlendState = BlendStateBase;
|
||||||
class Buffer;
|
class Buffer;
|
||||||
using BufferView = BufferViewBase;
|
using BufferView = BufferViewBase;
|
||||||
using CommandBuffer = CommandBufferBase;
|
class CommandBuffer;
|
||||||
using ComputePipeline = ComputePipelineBase;
|
using ComputePipeline = ComputePipelineBase;
|
||||||
using DepthStencilState = DepthStencilStateBase;
|
using DepthStencilState = DepthStencilStateBase;
|
||||||
class Device;
|
class Device;
|
||||||
|
|
|
@ -136,10 +136,10 @@ TEST_P(BufferSetSubDataTests, SmallDataAtOffset) {
|
||||||
|
|
||||||
// Stress test for many calls to SetSubData
|
// Stress test for many calls to SetSubData
|
||||||
TEST_P(BufferSetSubDataTests, ManySetSubData) {
|
TEST_P(BufferSetSubDataTests, ManySetSubData) {
|
||||||
if (IsD3D12() || IsMetal()) {
|
if (IsD3D12() || IsMetal() || IsVulkan()) {
|
||||||
// TODO(cwallez@chromium.org): Use ringbuffers for SetSubData on explicit APIs.
|
// TODO(cwallez@chromium.org): Use ringbuffers for SetSubData on explicit APIs.
|
||||||
// otherwise this creates too many resources and can take freeze the driver(?)
|
// otherwise this creates too many resources and can take freeze the driver(?)
|
||||||
std::cout << "Test skipped on D3D12 and Metal" << std::endl;
|
std::cout << "Test skipped on D3D12, Metal and Vulkan" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,4 +180,8 @@ TEST_P(BufferSetSubDataTests, LargeSetSubData) {
|
||||||
EXPECT_BUFFER_U32_RANGE_EQ(expectedData.data(), buffer, 0, kElements);
|
EXPECT_BUFFER_U32_RANGE_EQ(expectedData.data(), buffer, 0, kElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
NXT_INSTANTIATE_TEST(BufferSetSubDataTests, D3D12Backend, MetalBackend, OpenGLBackend)
|
NXT_INSTANTIATE_TEST(BufferSetSubDataTests,
|
||||||
|
D3D12Backend,
|
||||||
|
MetalBackend,
|
||||||
|
OpenGLBackend,
|
||||||
|
VulkanBackend)
|
||||||
|
|
Loading…
Reference in New Issue