Vulkan: Handle errors when creating VkRenderPass

BUG=dawn:19

Change-Id: I6007fb594a7c073b835554ca6914453a67608947
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11863
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2019-10-11 11:17:22 +00:00 committed by Commit Bot service account
parent 3b05a6e031
commit 18a5d42898
6 changed files with 39 additions and 32 deletions

View File

@ -29,6 +29,7 @@
#include "dawn_native/vulkan/RenderPipelineVk.h" #include "dawn_native/vulkan/RenderPipelineVk.h"
#include "dawn_native/vulkan/TextureVk.h" #include "dawn_native/vulkan/TextureVk.h"
#include "dawn_native/vulkan/UtilsVulkan.h" #include "dawn_native/vulkan/UtilsVulkan.h"
#include "dawn_native/vulkan/VulkanError.h"
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {
@ -105,9 +106,9 @@ namespace dawn_native { namespace vulkan {
} }
}; };
void RecordBeginRenderPass(CommandRecordingContext* recordingContext, MaybeError RecordBeginRenderPass(CommandRecordingContext* recordingContext,
Device* device, Device* device,
BeginRenderPassCmd* renderPass) { BeginRenderPassCmd* renderPass) {
VkCommandBuffer commands = recordingContext->commandBuffer; VkCommandBuffer commands = recordingContext->commandBuffer;
// Query a VkRenderPass from the cache // Query a VkRenderPass from the cache
@ -197,7 +198,7 @@ namespace dawn_native { namespace vulkan {
query.SetSampleCount(renderPass->attachmentState->GetSampleCount()); query.SetSampleCount(renderPass->attachmentState->GetSampleCount());
renderPassVK = device->GetRenderPassCache()->GetRenderPass(query); DAWN_TRY_ASSIGN(renderPassVK, device->GetRenderPassCache()->GetRenderPass(query));
} }
// Create a framebuffer that will be used once for the render pass and gather the clear // Create a framebuffer that will be used once for the render pass and gather the clear
@ -260,10 +261,10 @@ namespace dawn_native { namespace vulkan {
createInfo.height = renderPass->height; createInfo.height = renderPass->height;
createInfo.layers = 1; createInfo.layers = 1;
if (device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo, nullptr, DAWN_TRY(
&framebuffer) != VK_SUCCESS) { CheckVkSuccess(device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo,
ASSERT(false); nullptr, &framebuffer),
} "CreateFramebuffer"));
// We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the // We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the
// commands currently being recorded are finished. // commands currently being recorded are finished.
@ -283,6 +284,8 @@ namespace dawn_native { namespace vulkan {
beginInfo.pClearValues = clearValues.data(); beginInfo.pClearValues = clearValues.data();
device->fn.CmdBeginRenderPass(commands, &beginInfo, VK_SUBPASS_CONTENTS_INLINE); device->fn.CmdBeginRenderPass(commands, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
return {};
} }
} // anonymous namespace } // anonymous namespace
@ -354,7 +357,7 @@ namespace dawn_native { namespace vulkan {
recordingContext->tempBuffers.emplace_back(tempBuffer); recordingContext->tempBuffers.emplace_back(tempBuffer);
} }
void CommandBuffer::RecordCommands(CommandRecordingContext* recordingContext) { MaybeError CommandBuffer::RecordCommands(CommandRecordingContext* recordingContext) {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
VkCommandBuffer commands = recordingContext->commandBuffer; VkCommandBuffer commands = recordingContext->commandBuffer;
@ -525,7 +528,7 @@ namespace dawn_native { namespace vulkan {
BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>(); BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
TransitionForPass(recordingContext, passResourceUsages[nextPassNumber]); TransitionForPass(recordingContext, passResourceUsages[nextPassNumber]);
RecordRenderPass(recordingContext, cmd); DAWN_TRY(RecordRenderPass(recordingContext, cmd));
nextPassNumber++; nextPassNumber++;
} break; } break;
@ -542,6 +545,8 @@ namespace dawn_native { namespace vulkan {
default: { UNREACHABLE(); } break; default: { UNREACHABLE(); } break;
} }
} }
return {};
} }
void CommandBuffer::RecordComputePass(CommandRecordingContext* recordingContext) { void CommandBuffer::RecordComputePass(CommandRecordingContext* recordingContext) {
@ -649,12 +654,13 @@ namespace dawn_native { namespace vulkan {
// EndComputePass should have been called // EndComputePass should have been called
UNREACHABLE(); UNREACHABLE();
} }
void CommandBuffer::RecordRenderPass(CommandRecordingContext* recordingContext,
BeginRenderPassCmd* renderPassCmd) { MaybeError CommandBuffer::RecordRenderPass(CommandRecordingContext* recordingContext,
BeginRenderPassCmd* renderPassCmd) {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
VkCommandBuffer commands = recordingContext->commandBuffer; VkCommandBuffer commands = recordingContext->commandBuffer;
RecordBeginRenderPass(recordingContext, device, renderPassCmd); DAWN_TRY(RecordBeginRenderPass(recordingContext, device, renderPassCmd));
// Set the default value for the dynamic state // Set the default value for the dynamic state
{ {
@ -834,7 +840,7 @@ namespace dawn_native { namespace vulkan {
case Command::EndRenderPass: { case Command::EndRenderPass: {
mCommands.NextCommand<EndRenderPassCmd>(); mCommands.NextCommand<EndRenderPassCmd>();
device->fn.CmdEndRenderPass(commands); device->fn.CmdEndRenderPass(commands);
return; return {};
} break; } break;
case Command::SetBlendColor: { case Command::SetBlendColor: {

View File

@ -37,14 +37,14 @@ namespace dawn_native { namespace vulkan {
const CommandBufferDescriptor* descriptor); const CommandBufferDescriptor* descriptor);
~CommandBuffer(); ~CommandBuffer();
void RecordCommands(CommandRecordingContext* recordingContext); MaybeError RecordCommands(CommandRecordingContext* recordingContext);
private: private:
CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor); CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor);
void RecordComputePass(CommandRecordingContext* recordingContext); void RecordComputePass(CommandRecordingContext* recordingContext);
void RecordRenderPass(CommandRecordingContext* recordingContext, MaybeError RecordRenderPass(CommandRecordingContext* recordingContext,
BeginRenderPassCmd* renderPass); BeginRenderPassCmd* renderPass);
void RecordCopyImageWithTemporaryBuffer(CommandRecordingContext* recordingContext, void RecordCopyImageWithTemporaryBuffer(CommandRecordingContext* recordingContext,
const TextureCopy& srcCopy, const TextureCopy& srcCopy,
const TextureCopy& dstCopy, const TextureCopy& dstCopy,

View File

@ -35,7 +35,7 @@ namespace dawn_native { namespace vulkan {
CommandRecordingContext* recordingContext = device->GetPendingRecordingContext(); CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
for (uint32_t i = 0; i < commandCount; ++i) { for (uint32_t i = 0; i < commandCount; ++i) {
ToBackend(commands[i])->RecordCommands(recordingContext); DAWN_TRY(ToBackend(commands[i])->RecordCommands(recordingContext));
} }
device->SubmitPendingCommands(); device->SubmitPendingCommands();

View File

@ -18,6 +18,7 @@
#include "common/HashUtils.h" #include "common/HashUtils.h"
#include "dawn_native/vulkan/DeviceVk.h" #include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/TextureVk.h" #include "dawn_native/vulkan/TextureVk.h"
#include "dawn_native/vulkan/VulkanError.h"
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {
@ -71,18 +72,19 @@ namespace dawn_native { namespace vulkan {
mCache.clear(); mCache.clear();
} }
VkRenderPass RenderPassCache::GetRenderPass(const RenderPassCacheQuery& query) { ResultOrError<VkRenderPass> RenderPassCache::GetRenderPass(const RenderPassCacheQuery& query) {
auto it = mCache.find(query); auto it = mCache.find(query);
if (it != mCache.end()) { if (it != mCache.end()) {
return it->second; return VkRenderPass(it->second);
} }
VkRenderPass renderPass = CreateRenderPassForQuery(query); VkRenderPass renderPass;
DAWN_TRY_ASSIGN(renderPass, CreateRenderPassForQuery(query));
mCache.emplace(query, renderPass); mCache.emplace(query, renderPass);
return renderPass; return renderPass;
} }
VkRenderPass RenderPassCache::CreateRenderPassForQuery( ResultOrError<VkRenderPass> RenderPassCache::CreateRenderPassForQuery(
const RenderPassCacheQuery& query) const { const RenderPassCacheQuery& query) const {
// The Vulkan subpasses want to know the layout of the attachments with VkAttachmentRef. // The Vulkan subpasses want to know the layout of the attachments with VkAttachmentRef.
// Precompute them as they must be pointer-chained in VkSubpassDescription // Precompute them as they must be pointer-chained in VkSubpassDescription
@ -189,11 +191,9 @@ namespace dawn_native { namespace vulkan {
// Create the render pass from the zillion parameters // Create the render pass from the zillion parameters
VkRenderPass renderPass; VkRenderPass renderPass;
if (mDevice->fn.CreateRenderPass(mDevice->GetVkDevice(), &createInfo, nullptr, DAWN_TRY(CheckVkSuccess(
&renderPass) != VK_SUCCESS) { mDevice->fn.CreateRenderPass(mDevice->GetVkDevice(), &createInfo, nullptr, &renderPass),
ASSERT(false); "CreateRenderPass"));
}
return renderPass; return renderPass;
} }

View File

@ -15,9 +15,9 @@
#ifndef DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_ #ifndef DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_
#define DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_ #define DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_
#include "common/vulkan_platform.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "common/vulkan_platform.h"
#include "dawn_native/Error.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include <array> #include <array>
@ -66,11 +66,12 @@ namespace dawn_native { namespace vulkan {
RenderPassCache(Device* device); RenderPassCache(Device* device);
~RenderPassCache(); ~RenderPassCache();
VkRenderPass GetRenderPass(const RenderPassCacheQuery& query); ResultOrError<VkRenderPass> GetRenderPass(const RenderPassCacheQuery& query);
private: private:
// Does the actual VkRenderPass creation on a cache miss. // Does the actual VkRenderPass creation on a cache miss.
VkRenderPass CreateRenderPassForQuery(const RenderPassCacheQuery& query) const; ResultOrError<VkRenderPass> CreateRenderPassForQuery(
const RenderPassCacheQuery& query) const;
// Implements the functors necessary for to use RenderPassCacheQueries as unordered_map // Implements the functors necessary for to use RenderPassCacheQueries as unordered_map
// keys. // keys.

View File

@ -474,7 +474,7 @@ namespace dawn_native { namespace vulkan {
query.SetSampleCount(GetSampleCount()); query.SetSampleCount(GetSampleCount());
renderPass = device->GetRenderPassCache()->GetRenderPass(query); DAWN_TRY_ASSIGN(renderPass, device->GetRenderPassCache()->GetRenderPass(query));
} }
// The create info chains in a bunch of things created on the stack here or inside state // The create info chains in a bunch of things created on the stack here or inside state