Vulkan: Add proper error handling for all regular object creation.
This makes all the regular WebGPU object creation handle errors properly in the Vulkan backend instead of ASSERTing no Vulkan error is raised. Static Create functions are added to all these types so that the details of how the initialization is done is private, and it isn't possible to construct an object but forget to initialize it. BUG=dawn:19 Change-Id: I362b2d66b74dd7799ffbf69d732bc58caa97950b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11861 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
bc8e7ea286
commit
e986cb9254
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -60,8 +61,17 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
}
|
||||
|
||||
BindGroupLayout::BindGroupLayout(Device* device, const BindGroupLayoutDescriptor* descriptor)
|
||||
: BindGroupLayoutBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<BindGroupLayout*> BindGroupLayout::Create(
|
||||
Device* device,
|
||||
const BindGroupLayoutDescriptor* descriptor) {
|
||||
std::unique_ptr<BindGroupLayout> bgl =
|
||||
std::make_unique<BindGroupLayout>(device, descriptor);
|
||||
DAWN_TRY(bgl->Initialize());
|
||||
return bgl.release();
|
||||
}
|
||||
|
||||
MaybeError BindGroupLayout::Initialize() {
|
||||
const auto& info = GetBindingInfo();
|
||||
|
||||
// Compute the bindings that will be chained in the DescriptorSetLayout create info. We add
|
||||
|
@ -88,10 +98,10 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.bindingCount = numBindings;
|
||||
createInfo.pBindings = bindings.data();
|
||||
|
||||
if (device->fn.CreateDescriptorSetLayout(device->GetVkDevice(), &createInfo, nullptr,
|
||||
&mHandle) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
Device* device = ToBackend(GetDevice());
|
||||
return CheckVkSuccess(device->fn.CreateDescriptorSetLayout(device->GetVkDevice(),
|
||||
&createInfo, nullptr, &mHandle),
|
||||
"CreateDescriptorSetLayout");
|
||||
}
|
||||
|
||||
BindGroupLayout::~BindGroupLayout() {
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class BindGroupLayout : public BindGroupLayoutBase {
|
||||
public:
|
||||
BindGroupLayout(Device* device, const BindGroupLayoutDescriptor* descriptor);
|
||||
static ResultOrError<BindGroupLayout*> Create(Device* device,
|
||||
const BindGroupLayoutDescriptor* descriptor);
|
||||
~BindGroupLayout();
|
||||
|
||||
VkDescriptorSetLayout GetHandle() const;
|
||||
|
@ -37,6 +38,9 @@ namespace dawn_native { namespace vulkan {
|
|||
PoolSizeSpec ComputePoolSizes(uint32_t* numPoolSizes) const;
|
||||
|
||||
private:
|
||||
using BindGroupLayoutBase::BindGroupLayoutBase;
|
||||
MaybeError Initialize();
|
||||
|
||||
VkDescriptorSetLayout mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,19 +14,28 @@
|
|||
|
||||
#include "dawn_native/vulkan/BindGroupVk.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/vulkan/BindGroupLayoutVk.h"
|
||||
#include "dawn_native/vulkan/BufferVk.h"
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/SamplerVk.h"
|
||||
#include "dawn_native/vulkan/TextureVk.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
BindGroup::BindGroup(Device* device, const BindGroupDescriptor* descriptor)
|
||||
: BindGroupBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<BindGroup*> BindGroup::Create(Device* device,
|
||||
const BindGroupDescriptor* descriptor) {
|
||||
std::unique_ptr<BindGroup> group = std::make_unique<BindGroup>(device, descriptor);
|
||||
DAWN_TRY(group->Initialize());
|
||||
return group.release();
|
||||
}
|
||||
|
||||
MaybeError BindGroup::Initialize() {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
// Create a pool to hold our descriptor set.
|
||||
// TODO(cwallez@chromium.org): This horribly inefficient, find a way to be better, for
|
||||
// example by having one pool per bind group layout instead.
|
||||
|
@ -41,10 +50,9 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.poolSizeCount = numPoolSizes;
|
||||
createInfo.pPoolSizes = poolSizes.data();
|
||||
|
||||
if (device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo, nullptr, &mPool) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
DAWN_TRY(CheckVkSuccess(
|
||||
device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo, nullptr, &mPool),
|
||||
"CreateDescriptorPool"));
|
||||
|
||||
// Now do the allocation of one descriptor set, this is very suboptimal too.
|
||||
VkDescriptorSetLayout vkLayout = ToBackend(GetLayout())->GetHandle();
|
||||
|
@ -56,10 +64,9 @@ namespace dawn_native { namespace vulkan {
|
|||
allocateInfo.descriptorSetCount = 1;
|
||||
allocateInfo.pSetLayouts = &vkLayout;
|
||||
|
||||
if (device->fn.AllocateDescriptorSets(device->GetVkDevice(), &allocateInfo, &mHandle) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
DAWN_TRY(CheckVkSuccess(
|
||||
device->fn.AllocateDescriptorSets(device->GetVkDevice(), &allocateInfo, &mHandle),
|
||||
"AllocateDescriptorSets"));
|
||||
|
||||
// Now do a write of a single descriptor set with all possible chained data allocated on the
|
||||
// stack.
|
||||
|
@ -118,6 +125,8 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
device->fn.UpdateDescriptorSets(device->GetVkDevice(), numWrites, writes.data(), 0,
|
||||
nullptr);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BindGroup::~BindGroup() {
|
||||
|
|
|
@ -25,12 +25,16 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class BindGroup : public BindGroupBase {
|
||||
public:
|
||||
BindGroup(Device* device, const BindGroupDescriptor* descriptor);
|
||||
static ResultOrError<BindGroup*> Create(Device* device,
|
||||
const BindGroupDescriptor* descriptor);
|
||||
~BindGroup();
|
||||
|
||||
VkDescriptorSet GetHandle() const;
|
||||
|
||||
private:
|
||||
using BindGroupBase::BindGroupBase;
|
||||
MaybeError Initialize();
|
||||
|
||||
VkDescriptorPool mPool = VK_NULL_HANDLE;
|
||||
VkDescriptorSet mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
|
|
@ -114,8 +114,11 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
} // namespace
|
||||
|
||||
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
|
||||
: BufferBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<Buffer*> Buffer::Create(Device* device, const BufferDescriptor* descriptor) {
|
||||
std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(device, descriptor);
|
||||
DAWN_TRY(buffer->Initialize());
|
||||
return buffer.release();
|
||||
}
|
||||
|
||||
MaybeError Buffer::Initialize() {
|
||||
|
|
|
@ -29,11 +29,9 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class Buffer : public BufferBase {
|
||||
public:
|
||||
Buffer(Device* device, const BufferDescriptor* descriptor);
|
||||
static ResultOrError<Buffer*> Create(Device* device, const BufferDescriptor* descriptor);
|
||||
~Buffer();
|
||||
|
||||
MaybeError Initialize();
|
||||
|
||||
void OnMapReadCommandSerialFinished(uint32_t mapSerial, const void* data);
|
||||
void OnMapWriteCommandSerialFinished(uint32_t mapSerial, void* data);
|
||||
|
||||
|
@ -45,6 +43,9 @@ namespace dawn_native { namespace vulkan {
|
|||
void TransitionUsageNow(CommandRecordingContext* recordingContext, dawn::BufferUsage usage);
|
||||
|
||||
private:
|
||||
using BufferBase::BufferBase;
|
||||
MaybeError Initialize();
|
||||
|
||||
// Dawn API
|
||||
MaybeError MapReadAsyncImpl(uint32_t serial) override;
|
||||
MaybeError MapWriteAsyncImpl(uint32_t serial) override;
|
||||
|
|
|
@ -286,6 +286,12 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
CommandBuffer* CommandBuffer::Create(CommandEncoderBase* encoder,
|
||||
const CommandBufferDescriptor* descriptor) {
|
||||
return new CommandBuffer(encoder, descriptor);
|
||||
}
|
||||
|
||||
CommandBuffer::CommandBuffer(CommandEncoderBase* encoder,
|
||||
const CommandBufferDescriptor* descriptor)
|
||||
: CommandBufferBase(encoder, descriptor), mCommands(encoder->AcquireCommands()) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "dawn_native/CommandAllocator.h"
|
||||
#include "dawn_native/CommandBuffer.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
|
||||
|
@ -32,12 +33,15 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class CommandBuffer : public CommandBufferBase {
|
||||
public:
|
||||
CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor);
|
||||
static CommandBuffer* Create(CommandEncoderBase* encoder,
|
||||
const CommandBufferDescriptor* descriptor);
|
||||
~CommandBuffer();
|
||||
|
||||
void RecordCommands(CommandRecordingContext* recordingContext);
|
||||
|
||||
private:
|
||||
CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor);
|
||||
|
||||
void RecordComputePass(CommandRecordingContext* recordingContext);
|
||||
void RecordRenderPass(CommandRecordingContext* recordingContext,
|
||||
BeginRenderPassCmd* renderPass);
|
||||
|
|
|
@ -18,11 +18,21 @@
|
|||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
||||
#include "dawn_native/vulkan/ShaderModuleVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
ComputePipeline::ComputePipeline(Device* device, const ComputePipelineDescriptor* descriptor)
|
||||
: ComputePipelineBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<ComputePipeline*> ComputePipeline::Create(
|
||||
Device* device,
|
||||
const ComputePipelineDescriptor* descriptor) {
|
||||
std::unique_ptr<ComputePipeline> pipeline =
|
||||
std::make_unique<ComputePipeline>(device, descriptor);
|
||||
DAWN_TRY(pipeline->Initialize(descriptor));
|
||||
return pipeline.release();
|
||||
}
|
||||
|
||||
MaybeError ComputePipeline::Initialize(const ComputePipelineDescriptor* descriptor) {
|
||||
VkComputePipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
|
@ -39,10 +49,11 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.stage.pName = descriptor->computeStage.entryPoint;
|
||||
createInfo.stage.pSpecializationInfo = nullptr;
|
||||
|
||||
if (device->fn.CreateComputePipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1, &createInfo,
|
||||
nullptr, &mHandle) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
Device* device = ToBackend(GetDevice());
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreateComputePipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1, &createInfo,
|
||||
nullptr, &mHandle),
|
||||
"CreateComputePipeline");
|
||||
}
|
||||
|
||||
ComputePipeline::~ComputePipeline() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dawn_native/ComputePipeline.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -25,12 +26,16 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class ComputePipeline : public ComputePipelineBase {
|
||||
public:
|
||||
ComputePipeline(Device* device, const ComputePipelineDescriptor* descriptor);
|
||||
static ResultOrError<ComputePipeline*> Create(Device* device,
|
||||
const ComputePipelineDescriptor* descriptor);
|
||||
~ComputePipeline();
|
||||
|
||||
VkPipeline GetHandle() const;
|
||||
|
||||
private:
|
||||
using ComputePipelineBase::ComputePipelineBase;
|
||||
MaybeError Initialize(const ComputePipelineDescriptor* descriptor);
|
||||
|
||||
VkPipeline mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
|
@ -147,54 +147,52 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||
const BindGroupDescriptor* descriptor) {
|
||||
return new BindGroup(this, descriptor);
|
||||
return BindGroup::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||
const BindGroupLayoutDescriptor* descriptor) {
|
||||
return new BindGroupLayout(this, descriptor);
|
||||
return BindGroupLayout::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
|
||||
std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(this, descriptor);
|
||||
DAWN_TRY(buffer->Initialize());
|
||||
return buffer.release();
|
||||
return Buffer::Create(this, descriptor);
|
||||
}
|
||||
CommandBufferBase* Device::CreateCommandBuffer(CommandEncoderBase* encoder,
|
||||
const CommandBufferDescriptor* descriptor) {
|
||||
return new CommandBuffer(encoder, descriptor);
|
||||
return CommandBuffer::Create(encoder, descriptor);
|
||||
}
|
||||
ResultOrError<ComputePipelineBase*> Device::CreateComputePipelineImpl(
|
||||
const ComputePipelineDescriptor* descriptor) {
|
||||
return new ComputePipeline(this, descriptor);
|
||||
return ComputePipeline::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
return new PipelineLayout(this, descriptor);
|
||||
return PipelineLayout::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
||||
return new Queue(this);
|
||||
return Queue::Create(this);
|
||||
}
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
return new RenderPipeline(this, descriptor);
|
||||
return RenderPipeline::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||
return new Sampler(this, descriptor);
|
||||
return Sampler::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
|
||||
const ShaderModuleDescriptor* descriptor) {
|
||||
return new ShaderModule(this, descriptor);
|
||||
return ShaderModule::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
|
||||
const SwapChainDescriptor* descriptor) {
|
||||
return new SwapChain(this, descriptor);
|
||||
return SwapChain::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
|
||||
return new Texture(this, descriptor);
|
||||
return Texture::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl(
|
||||
TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor) {
|
||||
return new TextureView(texture, descriptor);
|
||||
return TextureView::Create(texture, descriptor);
|
||||
}
|
||||
|
||||
Serial Device::GetCompletedCommandSerial() const {
|
||||
|
|
|
@ -14,16 +14,25 @@
|
|||
|
||||
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/vulkan/BindGroupLayoutVk.h"
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
PipelineLayout::PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor)
|
||||
: PipelineLayoutBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<PipelineLayout*> PipelineLayout::Create(
|
||||
Device* device,
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
std::unique_ptr<PipelineLayout> layout =
|
||||
std::make_unique<PipelineLayout>(device, descriptor);
|
||||
DAWN_TRY(layout->Initialize());
|
||||
return layout.release();
|
||||
}
|
||||
|
||||
MaybeError PipelineLayout::Initialize() {
|
||||
// Compute the array of VkDescriptorSetLayouts that will be chained in the create info.
|
||||
// TODO(cwallez@chromium.org) Vulkan doesn't allow holes in this array, should we expose
|
||||
// this constraints at the Dawn level?
|
||||
|
@ -43,10 +52,10 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.pushConstantRangeCount = 0;
|
||||
createInfo.pPushConstantRanges = nullptr;
|
||||
|
||||
if (device->fn.CreatePipelineLayout(device->GetVkDevice(), &createInfo, nullptr,
|
||||
&mHandle) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
Device* device = ToBackend(GetDevice());
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreatePipelineLayout(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
|
||||
"CreatePipelineLayout");
|
||||
}
|
||||
|
||||
PipelineLayout::~PipelineLayout() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dawn_native/PipelineLayout.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -25,12 +26,16 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class PipelineLayout : public PipelineLayoutBase {
|
||||
public:
|
||||
PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor);
|
||||
static ResultOrError<PipelineLayout*> Create(Device* device,
|
||||
const PipelineLayoutDescriptor* descriptor);
|
||||
~PipelineLayout();
|
||||
|
||||
VkPipelineLayout GetHandle() const;
|
||||
|
||||
private:
|
||||
using PipelineLayoutBase::PipelineLayoutBase;
|
||||
MaybeError Initialize();
|
||||
|
||||
VkPipelineLayout mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
Queue::Queue(Device* device) : QueueBase(device) {
|
||||
// static
|
||||
Queue* Queue::Create(Device* device) {
|
||||
return new Queue(device);
|
||||
}
|
||||
|
||||
Queue::~Queue() {
|
||||
|
|
|
@ -24,10 +24,12 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class Queue : public QueueBase {
|
||||
public:
|
||||
Queue(Device* device);
|
||||
static Queue* Create(Device* device);
|
||||
~Queue();
|
||||
|
||||
private:
|
||||
using QueueBase::QueueBase;
|
||||
|
||||
MaybeError SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "dawn_native/vulkan/ShaderModuleVk.h"
|
||||
#include "dawn_native/vulkan/TextureVk.h"
|
||||
#include "dawn_native/vulkan/UtilsVulkan.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -318,8 +319,19 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<RenderPipeline*> RenderPipeline::Create(
|
||||
Device* device,
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
std::unique_ptr<RenderPipeline> pipeline =
|
||||
std::make_unique<RenderPipeline>(device, descriptor);
|
||||
DAWN_TRY(pipeline->Initialize(descriptor));
|
||||
return pipeline.release();
|
||||
}
|
||||
|
||||
MaybeError RenderPipeline::Initialize(const RenderPipelineDescriptor* descriptor) {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
VkPipelineShaderStageCreateInfo shaderStages[2];
|
||||
{
|
||||
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
|
@ -488,10 +500,10 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
createInfo.basePipelineIndex = -1;
|
||||
|
||||
if (device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1,
|
||||
&createInfo, nullptr, &mHandle) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1,
|
||||
&createInfo, nullptr, &mHandle),
|
||||
"CreateGraphicsPipeline");
|
||||
}
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dawn_native/RenderPipeline.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -25,12 +26,16 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
static ResultOrError<RenderPipeline*> Create(Device* device,
|
||||
const RenderPipelineDescriptor* descriptor);
|
||||
~RenderPipeline();
|
||||
|
||||
VkPipeline GetHandle() const;
|
||||
|
||||
private:
|
||||
using RenderPipelineBase::RenderPipelineBase;
|
||||
MaybeError Initialize(const RenderPipelineDescriptor* descriptor);
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo ComputeVertexInputDesc(
|
||||
const VertexInputDescriptor* vertexInput,
|
||||
std::array<VkVertexInputBindingDescription, kMaxVertexBuffers>* mBindings,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/UtilsVulkan.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -57,8 +58,14 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
} // anonymous namespace
|
||||
|
||||
Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
|
||||
: SamplerBase(device, descriptor), mDevice(device) {
|
||||
// static
|
||||
ResultOrError<Sampler*> Sampler::Create(Device* device, const SamplerDescriptor* descriptor) {
|
||||
std::unique_ptr<Sampler> sampler = std::make_unique<Sampler>(device, descriptor);
|
||||
DAWN_TRY(sampler->Initialize(descriptor));
|
||||
return sampler.release();
|
||||
}
|
||||
|
||||
MaybeError Sampler::Initialize(const SamplerDescriptor* descriptor) {
|
||||
VkSamplerCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
|
@ -78,15 +85,15 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.maxLod = descriptor->lodMaxClamp;
|
||||
createInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
|
||||
if (device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
Device* device = ToBackend(GetDevice());
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
|
||||
"CreateSampler");
|
||||
}
|
||||
|
||||
Sampler::~Sampler() {
|
||||
if (mHandle != VK_NULL_HANDLE) {
|
||||
mDevice->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
mHandle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,20 +18,23 @@
|
|||
#include "dawn_native/Sampler.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/Error.h"
|
||||
#include "dawn_native/vulkan/MemoryAllocator.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Sampler : public SamplerBase {
|
||||
public:
|
||||
Sampler(Device* device, const SamplerDescriptor* descriptor);
|
||||
static ResultOrError<Sampler*> Create(Device* device, const SamplerDescriptor* descriptor);
|
||||
~Sampler();
|
||||
|
||||
VkSampler GetHandle() const;
|
||||
|
||||
private:
|
||||
using SamplerBase::SamplerBase;
|
||||
MaybeError Initialize(const SamplerDescriptor* descriptor);
|
||||
|
||||
VkSampler mHandle = VK_NULL_HANDLE;
|
||||
Device* mDevice = nullptr;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
|
|
@ -16,13 +16,21 @@
|
|||
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
#include <spirv_cross.hpp>
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
|
||||
: ShaderModuleBase(device, descriptor) {
|
||||
// static
|
||||
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
|
||||
const ShaderModuleDescriptor* descriptor) {
|
||||
std::unique_ptr<ShaderModule> module = std::make_unique<ShaderModule>(device, descriptor);
|
||||
DAWN_TRY(module->Initialize(descriptor));
|
||||
return module.release();
|
||||
}
|
||||
|
||||
MaybeError ShaderModule::Initialize(const ShaderModuleDescriptor* descriptor) {
|
||||
// Use SPIRV-Cross to extract info from the SPIRV even if Vulkan consumes SPIRV. We want to
|
||||
// have a translation step eventually anyway.
|
||||
spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
|
||||
|
@ -35,10 +43,10 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.codeSize = descriptor->codeSize * sizeof(uint32_t);
|
||||
createInfo.pCode = descriptor->code;
|
||||
|
||||
if (device->fn.CreateShaderModule(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
Device* device = ToBackend(GetDevice());
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreateShaderModule(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
|
||||
"CreateShaderModule");
|
||||
}
|
||||
|
||||
ShaderModule::~ShaderModule() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dawn_native/ShaderModule.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -25,12 +26,16 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class ShaderModule : public ShaderModuleBase {
|
||||
public:
|
||||
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
|
||||
static ResultOrError<ShaderModule*> Create(Device* device,
|
||||
const ShaderModuleDescriptor* descriptor);
|
||||
~ShaderModule();
|
||||
|
||||
VkShaderModule GetHandle() const;
|
||||
|
||||
private:
|
||||
using ShaderModuleBase::ShaderModuleBase;
|
||||
MaybeError Initialize(const ShaderModuleDescriptor* descriptor);
|
||||
|
||||
VkShaderModule mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
// static
|
||||
SwapChain* SwapChain::Create(Device* device, const SwapChainDescriptor* descriptor) {
|
||||
return new SwapChain(device, descriptor);
|
||||
}
|
||||
|
||||
SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor)
|
||||
: SwapChainBase(device, descriptor) {
|
||||
const auto& im = GetImplementation();
|
||||
|
|
|
@ -25,10 +25,12 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class SwapChain : public SwapChainBase {
|
||||
public:
|
||||
SwapChain(Device* device, const SwapChainDescriptor* descriptor);
|
||||
static SwapChain* Create(Device* device, const SwapChainDescriptor* descriptor);
|
||||
~SwapChain();
|
||||
|
||||
protected:
|
||||
SwapChain(Device* device, const SwapChainDescriptor* descriptor);
|
||||
|
||||
TextureBase* GetNextTextureImpl(const TextureDescriptor* descriptor) override;
|
||||
MaybeError OnBeforePresent(TextureBase* texture) override;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/StagingBufferVk.h"
|
||||
#include "dawn_native/vulkan/UtilsVulkan.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
|
@ -395,8 +396,17 @@ namespace dawn_native { namespace vulkan {
|
|||
return {};
|
||||
}
|
||||
|
||||
Texture::Texture(Device* device, const TextureDescriptor* descriptor)
|
||||
: TextureBase(device, descriptor, TextureState::OwnedInternal) {
|
||||
// static
|
||||
ResultOrError<Texture*> Texture::Create(Device* device, const TextureDescriptor* descriptor) {
|
||||
std::unique_ptr<Texture> texture =
|
||||
std::make_unique<Texture>(device, descriptor, TextureState::OwnedInternal);
|
||||
DAWN_TRY(texture->InitializeAsInternalTexture());
|
||||
return texture.release();
|
||||
}
|
||||
|
||||
MaybeError Texture::InitializeAsInternalTexture() {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
// Create the Vulkan image "container". We don't need to check that the format supports the
|
||||
// combination of sample, usage etc. because validation should have been done in the Dawn
|
||||
// frontend already based on the minimum supported formats in the Vulkan spec
|
||||
|
@ -428,29 +438,30 @@ namespace dawn_native { namespace vulkan {
|
|||
// also required for the implementation of robust resource initialization.
|
||||
createInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
if (device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
DAWN_TRY(CheckVkSuccess(
|
||||
device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
|
||||
"CreateImage"));
|
||||
|
||||
// Create the image memory and associate it with the container
|
||||
VkMemoryRequirements requirements;
|
||||
device->fn.GetImageMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
|
||||
|
||||
if (!device->GetMemoryAllocator()->Allocate(requirements, false, &mMemoryAllocation)) {
|
||||
ASSERT(false);
|
||||
return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate texture");
|
||||
}
|
||||
|
||||
if (device->fn.BindImageMemory(device->GetVkDevice(), mHandle,
|
||||
mMemoryAllocation.GetMemory(),
|
||||
mMemoryAllocation.GetMemoryOffset()) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
DAWN_TRY(CheckVkSuccess(device->fn.BindImageMemory(device->GetVkDevice(), mHandle,
|
||||
mMemoryAllocation.GetMemory(),
|
||||
mMemoryAllocation.GetMemoryOffset()),
|
||||
"BindImageMemory"));
|
||||
|
||||
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
|
||||
device->ConsumedError(ClearTexture(ToBackend(GetDevice())->GetPendingRecordingContext(),
|
||||
0, GetNumMipLevels(), 0, GetArrayLayers(),
|
||||
TextureBase::ClearValue::NonZero));
|
||||
DAWN_TRY(ClearTexture(ToBackend(GetDevice())->GetPendingRecordingContext(), 0,
|
||||
GetNumMipLevels(), 0, GetArrayLayers(),
|
||||
TextureBase::ClearValue::NonZero));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// With this constructor, the lifetime of the resource is externally managed.
|
||||
|
@ -756,10 +767,16 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(jiawei.shao@intel.com): create texture view by TextureViewDescriptor
|
||||
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
||||
: TextureViewBase(texture, descriptor) {
|
||||
Device* device = ToBackend(texture->GetDevice());
|
||||
// static
|
||||
ResultOrError<TextureView*> TextureView::Create(TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor) {
|
||||
std::unique_ptr<TextureView> view = std::make_unique<TextureView>(texture, descriptor);
|
||||
DAWN_TRY(view->Initialize(descriptor));
|
||||
return view.release();
|
||||
}
|
||||
|
||||
MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) {
|
||||
Device* device = ToBackend(GetTexture()->GetDevice());
|
||||
|
||||
VkImageViewCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
|
@ -776,10 +793,9 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.subresourceRange.baseArrayLayer = descriptor->baseArrayLayer;
|
||||
createInfo.subresourceRange.layerCount = descriptor->arrayLayerCount;
|
||||
|
||||
if (device->fn.CreateImageView(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreateImageView(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
|
||||
"CreateImageView");
|
||||
}
|
||||
|
||||
TextureView::~TextureView() {
|
||||
|
|
|
@ -35,15 +35,7 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class Texture : public TextureBase {
|
||||
public:
|
||||
enum class ExternalState {
|
||||
InternalOnly,
|
||||
PendingAcquire,
|
||||
Acquired,
|
||||
PendingRelease,
|
||||
Released
|
||||
};
|
||||
|
||||
Texture(Device* device, const TextureDescriptor* descriptor);
|
||||
static ResultOrError<Texture*> Create(Device* device, const TextureDescriptor* descriptor);
|
||||
Texture(Device* device, const TextureDescriptor* descriptor, VkImage nativeImage);
|
||||
Texture(Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
|
@ -70,6 +62,9 @@ namespace dawn_native { namespace vulkan {
|
|||
MaybeError SignalAndDestroy(VkSemaphore* outSignalSemaphore);
|
||||
|
||||
private:
|
||||
using TextureBase::TextureBase;
|
||||
MaybeError InitializeAsInternalTexture();
|
||||
|
||||
void DestroyImpl() override;
|
||||
MaybeError ClearTexture(CommandRecordingContext* recordingContext,
|
||||
uint32_t baseMipLevel,
|
||||
|
@ -82,24 +77,36 @@ namespace dawn_native { namespace vulkan {
|
|||
DeviceMemoryAllocation mMemoryAllocation;
|
||||
VkDeviceMemory mExternalAllocation = VK_NULL_HANDLE;
|
||||
|
||||
enum class ExternalState {
|
||||
InternalOnly,
|
||||
PendingAcquire,
|
||||
Acquired,
|
||||
PendingRelease,
|
||||
Released
|
||||
};
|
||||
ExternalState mExternalState = ExternalState::InternalOnly;
|
||||
ExternalState mLastExternalState = ExternalState::InternalOnly;
|
||||
|
||||
VkSemaphore mSignalSemaphore = VK_NULL_HANDLE;
|
||||
std::vector<VkSemaphore> mWaitRequirements;
|
||||
|
||||
// A usage of none will make sure the texture is transitioned before its first use as
|
||||
// required by the spec.
|
||||
// required by the Vulkan spec.
|
||||
dawn::TextureUsage mLastUsage = dawn::TextureUsage::None;
|
||||
};
|
||||
|
||||
class TextureView : public TextureViewBase {
|
||||
public:
|
||||
TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);
|
||||
static ResultOrError<TextureView*> Create(TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor);
|
||||
~TextureView();
|
||||
|
||||
VkImageView GetHandle() const;
|
||||
|
||||
private:
|
||||
using TextureViewBase::TextureViewBase;
|
||||
MaybeError Initialize(const TextureViewDescriptor* descriptor);
|
||||
|
||||
VkImageView mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue