D3D12 replace ASSERT_SUCCESS with better error handling

Added D3D12Error to check HRESULTS and return error messages
with the correct error names.

Remove ASSERT_SUCCESS from D3D12 backend and use
MaybeError and ResultError instead to handle errors.


Bug: dawn:19
Change-Id: Idf2f1987725e7e658bd29a9b13653125ab43c564
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12000
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Natasha Lee 2019-10-16 09:26:54 +00:00 committed by Commit Bot service account
parent c7d535bd72
commit f3d50baf85
15 changed files with 175 additions and 64 deletions

View File

@ -260,6 +260,8 @@ source_set("libdawn_native_sources") {
"src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.h", "src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.h",
"src/dawn_native/d3d12/ComputePipelineD3D12.cpp", "src/dawn_native/d3d12/ComputePipelineD3D12.cpp",
"src/dawn_native/d3d12/ComputePipelineD3D12.h", "src/dawn_native/d3d12/ComputePipelineD3D12.h",
"src/dawn_native/d3d12/D3D12Error.cpp",
"src/dawn_native/d3d12/D3D12Error.h",
"src/dawn_native/d3d12/D3D12Info.cpp", "src/dawn_native/d3d12/D3D12Info.cpp",
"src/dawn_native/d3d12/D3D12Info.h", "src/dawn_native/d3d12/D3D12Info.h",
"src/dawn_native/d3d12/DescriptorHeapAllocator.cpp", "src/dawn_native/d3d12/DescriptorHeapAllocator.cpp",

View File

@ -18,6 +18,7 @@
#include "common/Constants.h" #include "common/Constants.h"
#include "common/Math.h" #include "common/Math.h"
#include "dawn_native/d3d12/CommandRecordingContext.h" #include "dawn_native/d3d12/CommandRecordingContext.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/DeviceD3D12.h"
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
@ -217,8 +218,9 @@ namespace dawn_native { namespace d3d12 {
MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) { MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
mWrittenMappedRange = {0, GetSize()}; mWrittenMappedRange = {0, GetSize()};
ASSERT_SUCCESS(GetD3D12Resource()->Map(0, &mWrittenMappedRange, DAWN_TRY(CheckHRESULT(GetD3D12Resource()->Map(0, &mWrittenMappedRange,
reinterpret_cast<void**>(mappedPointer))); reinterpret_cast<void**>(mappedPointer)),
"D3D12 map at creation"));
return {}; return {};
} }
@ -226,7 +228,9 @@ namespace dawn_native { namespace d3d12 {
mWrittenMappedRange = {}; mWrittenMappedRange = {};
D3D12_RANGE readRange = {0, GetSize()}; D3D12_RANGE readRange = {0, GetSize()};
char* data = nullptr; char* data = nullptr;
ASSERT_SUCCESS(GetD3D12Resource()->Map(0, &readRange, reinterpret_cast<void**>(&data))); DAWN_TRY(
CheckHRESULT(GetD3D12Resource()->Map(0, &readRange, reinterpret_cast<void**>(&data)),
"D3D12 map read async"));
// There is no need to transition the resource to a new state: D3D12 seems to make the GPU // There is no need to transition the resource to a new state: D3D12 seems to make the GPU
// writes available when the fence is passed. // writes available when the fence is passed.
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker(); MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
@ -237,8 +241,9 @@ namespace dawn_native { namespace d3d12 {
MaybeError Buffer::MapWriteAsyncImpl(uint32_t serial) { MaybeError Buffer::MapWriteAsyncImpl(uint32_t serial) {
mWrittenMappedRange = {0, GetSize()}; mWrittenMappedRange = {0, GetSize()};
char* data = nullptr; char* data = nullptr;
ASSERT_SUCCESS( DAWN_TRY(CheckHRESULT(
GetD3D12Resource()->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(&data))); GetD3D12Resource()->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(&data)),
"D3D12 map write async"));
// There is no need to transition the resource to a new state: D3D12 seems to make the CPU // There is no need to transition the resource to a new state: D3D12 seems to make the CPU
// writes available on queue submission. // writes available on queue submission.
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker(); MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();

View File

@ -14,6 +14,7 @@
#include "dawn_native/d3d12/CommandAllocatorManager.h" #include "dawn_native/d3d12/CommandAllocatorManager.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/DeviceD3D12.h"
#include "common/Assert.h" #include "common/Assert.h"
@ -26,12 +27,12 @@ namespace dawn_native { namespace d3d12 {
mFreeAllocators.set(); mFreeAllocators.set();
} }
ComPtr<ID3D12CommandAllocator> CommandAllocatorManager::ReserveCommandAllocator() { ResultOrError<ID3D12CommandAllocator*> CommandAllocatorManager::ReserveCommandAllocator() {
// If there are no free allocators, get the oldest serial in flight and wait on it // If there are no free allocators, get the oldest serial in flight and wait on it
if (mFreeAllocators.none()) { if (mFreeAllocators.none()) {
const uint64_t firstSerial = mInFlightCommandAllocators.FirstSerial(); const uint64_t firstSerial = mInFlightCommandAllocators.FirstSerial();
device->WaitForSerial(firstSerial); DAWN_TRY(device->WaitForSerial(firstSerial));
Tick(firstSerial); DAWN_TRY(Tick(firstSerial));
} }
ASSERT(mFreeAllocators.any()); ASSERT(mFreeAllocators.any());
@ -42,8 +43,10 @@ namespace dawn_native { namespace d3d12 {
if (firstFreeIndex >= mAllocatorCount) { if (firstFreeIndex >= mAllocatorCount) {
ASSERT(firstFreeIndex == mAllocatorCount); ASSERT(firstFreeIndex == mAllocatorCount);
mAllocatorCount++; mAllocatorCount++;
ASSERT_SUCCESS(device->GetD3D12Device()->CreateCommandAllocator( DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateCommandAllocator(
D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex]))); D3D12_COMMAND_LIST_TYPE_DIRECT,
IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex])),
"D3D12 create command allocator"));
} }
// Mark the command allocator as used // Mark the command allocator as used
@ -53,17 +56,17 @@ namespace dawn_native { namespace d3d12 {
// ExecuteCommandLists // ExecuteCommandLists
mInFlightCommandAllocators.Enqueue({mCommandAllocators[firstFreeIndex], firstFreeIndex}, mInFlightCommandAllocators.Enqueue({mCommandAllocators[firstFreeIndex], firstFreeIndex},
device->GetPendingCommandSerial()); device->GetPendingCommandSerial());
return mCommandAllocators[firstFreeIndex].Get();
return mCommandAllocators[firstFreeIndex];
} }
void CommandAllocatorManager::Tick(uint64_t lastCompletedSerial) { MaybeError CommandAllocatorManager::Tick(uint64_t lastCompletedSerial) {
// Reset all command allocators that are no longer in flight // Reset all command allocators that are no longer in flight
for (auto it : mInFlightCommandAllocators.IterateUpTo(lastCompletedSerial)) { for (auto it : mInFlightCommandAllocators.IterateUpTo(lastCompletedSerial)) {
ASSERT_SUCCESS(it.commandAllocator->Reset()); DAWN_TRY(CheckHRESULT(it.commandAllocator->Reset(), "D3D12 reset command allocator"));
mFreeAllocators.set(it.index); mFreeAllocators.set(it.index);
} }
mInFlightCommandAllocators.ClearUpTo(lastCompletedSerial); mInFlightCommandAllocators.ClearUpTo(lastCompletedSerial);
return {};
} }
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -18,6 +18,7 @@
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "dawn_native/Error.h"
#include <bitset> #include <bitset>
@ -31,8 +32,8 @@ namespace dawn_native { namespace d3d12 {
// A CommandAllocator that is reserved must be used on the next ExecuteCommandLists // A CommandAllocator that is reserved must be used on the next ExecuteCommandLists
// otherwise its commands may be reset before execution has completed on the GPU // otherwise its commands may be reset before execution has completed on the GPU
ComPtr<ID3D12CommandAllocator> ReserveCommandAllocator(); ResultOrError<ID3D12CommandAllocator*> ReserveCommandAllocator();
void Tick(uint64_t lastCompletedSerial); MaybeError Tick(uint64_t lastCompletedSerial);
private: private:
Device* device; Device* device;

View File

@ -13,28 +13,28 @@
// limitations under the License. // limitations under the License.
#include "dawn_native/d3d12/CommandRecordingContext.h" #include "dawn_native/d3d12/CommandRecordingContext.h"
#include "dawn_native/d3d12/CommandAllocatorManager.h" #include "dawn_native/d3d12/CommandAllocatorManager.h"
#include "dawn_native/d3d12/D3D12Error.h"
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
MaybeError CommandRecordingContext::Open(ID3D12Device* d3d12Device, MaybeError CommandRecordingContext::Open(ID3D12Device* d3d12Device,
CommandAllocatorManager* commandAllocationManager) { CommandAllocatorManager* commandAllocationManager) {
ASSERT(!IsOpen()); ASSERT(!IsOpen());
ID3D12CommandAllocator* commandAllocator;
DAWN_TRY_ASSIGN(commandAllocator, commandAllocationManager->ReserveCommandAllocator());
if (mD3d12CommandList != nullptr) { if (mD3d12CommandList != nullptr) {
const HRESULT hr = mD3d12CommandList->Reset( MaybeError error = CheckHRESULT(mD3d12CommandList->Reset(commandAllocator, nullptr),
commandAllocationManager->ReserveCommandAllocator().Get(), nullptr); "D3D12 resetting command list");
if (FAILED(hr)) { if (error.IsError()) {
mD3d12CommandList.Reset(); mD3d12CommandList.Reset();
return DAWN_DEVICE_LOST_ERROR("Error resetting command list."); DAWN_TRY(std::move(error));
} }
} else { } else {
ComPtr<ID3D12GraphicsCommandList> d3d12GraphicsCommandList; ComPtr<ID3D12GraphicsCommandList> d3d12GraphicsCommandList;
const HRESULT hr = d3d12Device->CreateCommandList( DAWN_TRY(CheckHRESULT(
0, D3D12_COMMAND_LIST_TYPE_DIRECT, d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator,
commandAllocationManager->ReserveCommandAllocator().Get(), nullptr, nullptr, IID_PPV_ARGS(&d3d12GraphicsCommandList)),
IID_PPV_ARGS(&d3d12GraphicsCommandList)); "D3D12 creating direct command list"));
if (FAILED(hr)) {
return DAWN_DEVICE_LOST_ERROR("Error creating a direct command list.");
}
mD3d12CommandList = std::move(d3d12GraphicsCommandList); mD3d12CommandList = std::move(d3d12GraphicsCommandList);
} }
@ -46,10 +46,11 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<ID3D12GraphicsCommandList*> CommandRecordingContext::Close() { ResultOrError<ID3D12GraphicsCommandList*> CommandRecordingContext::Close() {
ASSERT(IsOpen()); ASSERT(IsOpen());
mIsOpen = false; mIsOpen = false;
const HRESULT hr = mD3d12CommandList->Close(); MaybeError error =
if (FAILED(hr)) { CheckHRESULT(mD3d12CommandList->Close(), "D3D12 closing pending command list");
if (error.IsError()) {
mD3d12CommandList.Reset(); mD3d12CommandList.Reset();
return DAWN_DEVICE_LOST_ERROR("Error closing pending command list."); DAWN_TRY(std::move(error));
} }
return mD3d12CommandList.Get(); return mD3d12CommandList.Get();
} }

View File

@ -0,0 +1,29 @@
// Copyright 2019 The Dawn 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 "dawn_native/d3d12/D3D12Error.h"
#include <string>
namespace dawn_native { namespace d3d12 {
MaybeError CheckHRESULT(HRESULT result, const char* context) {
if (DAWN_LIKELY(SUCCEEDED(result))) {
return {};
}
std::string message = std::string(context) + " failed with " + std::to_string(result);
return DAWN_DEVICE_LOST_ERROR(message);
}
}} // namespace dawn_native::d3d12

View File

@ -0,0 +1,28 @@
// Copyright 2019 The Dawn 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 DAWNNATIVE_D3D12_D3D12ERROR_H_
#define DAWNNATIVE_D3D12_D3D12ERROR_H_
#include <d3d12.h>
#include "dawn_native/Error.h"
namespace dawn_native { namespace d3d12 {
// Returns a success only if result of HResult is success
MaybeError CheckHRESULT(HRESULT result, const char* context);
}} // namespace dawn_native::d3d12
#endif // DAWNNATIVE_D3D12_D3D12ERROR_H_

View File

@ -25,6 +25,7 @@
#include "dawn_native/d3d12/CommandAllocatorManager.h" #include "dawn_native/d3d12/CommandAllocatorManager.h"
#include "dawn_native/d3d12/CommandBufferD3D12.h" #include "dawn_native/d3d12/CommandBufferD3D12.h"
#include "dawn_native/d3d12/ComputePipelineD3D12.h" #include "dawn_native/d3d12/ComputePipelineD3D12.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DescriptorHeapAllocator.h" #include "dawn_native/d3d12/DescriptorHeapAllocator.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h" #include "dawn_native/d3d12/PlatformFunctions.h"
@ -56,10 +57,14 @@ namespace dawn_native { namespace d3d12 {
D3D12_COMMAND_QUEUE_DESC queueDesc = {}; D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
ASSERT_SUCCESS(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue))); DAWN_TRY(
CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
"D3D12 create command queue"));
DAWN_TRY(CheckHRESULT(mD3d12Device->CreateFence(mLastSubmittedSerial, D3D12_FENCE_FLAG_NONE,
IID_PPV_ARGS(&mFence)),
"D3D12 create fence"));
ASSERT_SUCCESS(mD3d12Device->CreateFence(mLastSubmittedSerial, D3D12_FENCE_FLAG_NONE,
IID_PPV_ARGS(&mFence)));
mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
ASSERT(mFenceEvent != nullptr); ASSERT(mFenceEvent != nullptr);
@ -70,7 +75,7 @@ namespace dawn_native { namespace d3d12 {
mResourceAllocator = std::make_unique<ResourceAllocator>(this); mResourceAllocator = std::make_unique<ResourceAllocator>(this);
mResourceAllocatorManager = std::make_unique<ResourceAllocatorManager>(this); mResourceAllocatorManager = std::make_unique<ResourceAllocatorManager>(this);
NextSerial(); DAWN_TRY(NextSerial());
// Initialize indirect commands // Initialize indirect commands
D3D12_INDIRECT_ARGUMENT_DESC argumentDesc = {}; D3D12_INDIRECT_ARGUMENT_DESC argumentDesc = {};
@ -103,8 +108,9 @@ namespace dawn_native { namespace d3d12 {
// Immediately forget about all pending commands // Immediately forget about all pending commands
mPendingCommands.Release(); mPendingCommands.Release();
NextSerial(); ConsumedError(NextSerial());
WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing // Wait for all in-flight commands to finish executing
ConsumedError(WaitForSerial(mLastSubmittedSerial));
// Call tick one last time so resources are cleaned up. Ignore the return value so we can // Call tick one last time so resources are cleaned up. Ignore the return value so we can
// continue shutting down in an orderly fashion. // continue shutting down in an orderly fashion.
@ -207,27 +213,29 @@ namespace dawn_native { namespace d3d12 {
mDynamicUploader->Deallocate(mCompletedSerial); mDynamicUploader->Deallocate(mCompletedSerial);
mResourceAllocator->Tick(mCompletedSerial); mResourceAllocator->Tick(mCompletedSerial);
mCommandAllocatorManager->Tick(mCompletedSerial); DAWN_TRY(mCommandAllocatorManager->Tick(mCompletedSerial));
mDescriptorHeapAllocator->Deallocate(mCompletedSerial); mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
mMapRequestTracker->Tick(mCompletedSerial); mMapRequestTracker->Tick(mCompletedSerial);
mUsedComObjectRefs.ClearUpTo(mCompletedSerial); mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
DAWN_TRY(ExecuteCommandContext(nullptr)); DAWN_TRY(ExecuteCommandContext(nullptr));
NextSerial(); DAWN_TRY(NextSerial());
return {}; return {};
} }
void Device::NextSerial() { MaybeError Device::NextSerial() {
mLastSubmittedSerial++; mLastSubmittedSerial++;
ASSERT_SUCCESS(mCommandQueue->Signal(mFence.Get(), mLastSubmittedSerial)); return CheckHRESULT(mCommandQueue->Signal(mFence.Get(), mLastSubmittedSerial),
"D3D12 command queue signal fence");
} }
void Device::WaitForSerial(uint64_t serial) { MaybeError Device::WaitForSerial(uint64_t serial) {
mCompletedSerial = mFence->GetCompletedValue(); mCompletedSerial = mFence->GetCompletedValue();
if (mCompletedSerial < serial) { if (mCompletedSerial < serial) {
ASSERT_SUCCESS(mFence->SetEventOnCompletion(serial, mFenceEvent)); DAWN_TRY(CheckHRESULT(mFence->SetEventOnCompletion(serial, mFenceEvent),
"D3D12 set event on completion"));
WaitForSingleObject(mFenceEvent, INFINITE); WaitForSingleObject(mFenceEvent, INFINITE);
} }
return {};
} }
void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) { void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) {
@ -279,14 +287,14 @@ namespace dawn_native { namespace d3d12 {
} }
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl( ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) { const PipelineLayoutDescriptor* descriptor) {
return new PipelineLayout(this, descriptor); return PipelineLayout::Create(this, descriptor);
} }
ResultOrError<QueueBase*> Device::CreateQueueImpl() { ResultOrError<QueueBase*> Device::CreateQueueImpl() {
return new Queue(this); return new Queue(this);
} }
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl( ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) { const RenderPipelineDescriptor* descriptor) {
return new RenderPipeline(this, descriptor); return RenderPipeline::Create(this, descriptor);
} }
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) { ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor); return new Sampler(this, descriptor);

View File

@ -73,8 +73,8 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<CommandRecordingContext*> GetPendingCommandContext(); ResultOrError<CommandRecordingContext*> GetPendingCommandContext();
Serial GetPendingCommandSerial() const override; Serial GetPendingCommandSerial() const override;
void NextSerial(); MaybeError NextSerial();
void WaitForSerial(Serial serial); MaybeError WaitForSerial(Serial serial);
void ReferenceUntilUnused(ComPtr<IUnknown> object); void ReferenceUntilUnused(ComPtr<IUnknown> object);

View File

@ -95,7 +95,7 @@ namespace dawn_native { namespace d3d12 {
// TODO(cwallez@chromium.org) Currently we force the CPU to wait for the GPU to be finished // TODO(cwallez@chromium.org) Currently we force the CPU to wait for the GPU to be finished
// with the buffer. Ideally the synchronization should be all done on the GPU. // with the buffer. Ideally the synchronization should be all done on the GPU.
mDevice->WaitForSerial(mBufferSerials[mCurrentBuffer]); ASSERT(mDevice->WaitForSerial(mBufferSerials[mCurrentBuffer]).IsSuccess());
return DAWN_SWAP_CHAIN_NO_ERROR; return DAWN_SWAP_CHAIN_NO_ERROR;
} }
@ -105,7 +105,7 @@ namespace dawn_native { namespace d3d12 {
ASSERT_SUCCESS(mSwapChain->Present(1, 0)); ASSERT_SUCCESS(mSwapChain->Present(1, 0));
// TODO(cwallez@chromium.org): Make the serial ticking implicit. // TODO(cwallez@chromium.org): Make the serial ticking implicit.
mDevice->NextSerial(); ASSERT(mDevice->NextSerial().IsSuccess());
mBufferSerials[mCurrentBuffer] = mDevice->GetPendingCommandSerial(); mBufferSerials[mCurrentBuffer] = mDevice->GetPendingCommandSerial();
return DAWN_SWAP_CHAIN_NO_ERROR; return DAWN_SWAP_CHAIN_NO_ERROR;

View File

@ -17,6 +17,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "common/BitSetIterator.h" #include "common/BitSetIterator.h"
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h" #include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h" #include "dawn_native/d3d12/PlatformFunctions.h"
@ -54,8 +55,17 @@ namespace dawn_native { namespace d3d12 {
} }
} // anonymous namespace } // anonymous namespace
PipelineLayout::PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor) ResultOrError<PipelineLayout*> PipelineLayout::Create(
: PipelineLayoutBase(device, descriptor) { 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() {
Device* device = ToBackend(GetDevice());
D3D12_ROOT_PARAMETER rootParameters[kMaxBindGroups * 2 + kMaxDynamicBufferCount]; D3D12_ROOT_PARAMETER rootParameters[kMaxBindGroups * 2 + kMaxDynamicBufferCount];
// A root parameter is one of these types // A root parameter is one of these types
@ -148,11 +158,15 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error; ComPtr<ID3DBlob> error;
ASSERT_SUCCESS(device->GetFunctions()->d3d12SerializeRootSignature( DAWN_TRY(CheckHRESULT(
&rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); device->GetFunctions()->d3d12SerializeRootSignature(
ASSERT_SUCCESS(device->GetD3D12Device()->CreateRootSignature( &rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error),
0, signature->GetBufferPointer(), signature->GetBufferSize(), "D3D12 serialize root signature"));
IID_PPV_ARGS(&mRootSignature))); DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateRootSignature(
0, signature->GetBufferPointer(), signature->GetBufferSize(),
IID_PPV_ARGS(&mRootSignature)),
"D3D12 create root signature"));
return {};
} }
uint32_t PipelineLayout::GetCbvUavSrvRootParameterIndex(uint32_t group) const { uint32_t PipelineLayout::GetCbvUavSrvRootParameterIndex(uint32_t group) const {

View File

@ -25,7 +25,8 @@ namespace dawn_native { namespace d3d12 {
class PipelineLayout : public PipelineLayoutBase { class PipelineLayout : public PipelineLayoutBase {
public: public:
PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor); static ResultOrError<PipelineLayout*> Create(Device* device,
const PipelineLayoutDescriptor* descriptor);
uint32_t GetCbvUavSrvRootParameterIndex(uint32_t group) const; uint32_t GetCbvUavSrvRootParameterIndex(uint32_t group) const;
uint32_t GetSamplerRootParameterIndex(uint32_t group) const; uint32_t GetSamplerRootParameterIndex(uint32_t group) const;
@ -36,6 +37,8 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3D12RootSignature> GetRootSignature() const; ComPtr<ID3D12RootSignature> GetRootSignature() const;
private: private:
using PipelineLayoutBase::PipelineLayoutBase;
MaybeError Initialize();
std::array<uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo; std::array<uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo;
std::array<uint32_t, kMaxBindGroups> mSamplerRootParameterInfo; std::array<uint32_t, kMaxBindGroups> mSamplerRootParameterInfo;
std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups> std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>

View File

@ -15,6 +15,7 @@
#include "dawn_native/d3d12/QueueD3D12.h" #include "dawn_native/d3d12/QueueD3D12.h"
#include "dawn_native/d3d12/CommandBufferD3D12.h" #include "dawn_native/d3d12/CommandBufferD3D12.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/DeviceD3D12.h"
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
@ -35,7 +36,7 @@ namespace dawn_native { namespace d3d12 {
DAWN_TRY(device->ExecuteCommandContext(&mCommandContext)); DAWN_TRY(device->ExecuteCommandContext(&mCommandContext));
device->NextSerial(); DAWN_TRY(device->NextSerial());
return {}; return {};
} }

View File

@ -15,6 +15,7 @@
#include "dawn_native/d3d12/RenderPipelineD3D12.h" #include "dawn_native/d3d12/RenderPipelineD3D12.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h" #include "dawn_native/d3d12/PlatformFunctions.h"
@ -288,9 +289,17 @@ namespace dawn_native { namespace d3d12 {
} // anonymous namespace } // anonymous namespace
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor) ResultOrError<RenderPipeline*> RenderPipeline::Create(
: RenderPipelineBase(device, descriptor), Device* device,
mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())) { 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());
uint32_t compileFlags = 0; uint32_t compileFlags = 0;
#if defined(_DEBUG) #if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools. // Enable better shader debugging with the graphics debugging tools.
@ -391,8 +400,12 @@ namespace dawn_native { namespace d3d12 {
descriptorD3D12.SampleDesc.Count = GetSampleCount(); descriptorD3D12.SampleDesc.Count = GetSampleCount();
descriptorD3D12.SampleDesc.Quality = 0; descriptorD3D12.SampleDesc.Quality = 0;
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState( mD3d12PrimitiveTopology = D3D12PrimitiveTopology(GetPrimitiveTopology());
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)));
DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateGraphicsPipelineState(
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)),
"D3D12 create graphics pipeline state"));
return {};
} }
RenderPipeline::~RenderPipeline() { RenderPipeline::~RenderPipeline() {

View File

@ -25,13 +25,16 @@ namespace dawn_native { namespace d3d12 {
class RenderPipeline : public RenderPipelineBase { class RenderPipeline : public RenderPipelineBase {
public: public:
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor); static ResultOrError<RenderPipeline*> Create(Device* device,
const RenderPipelineDescriptor* descriptor);
~RenderPipeline(); ~RenderPipeline();
D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const; D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const;
ComPtr<ID3D12PipelineState> GetPipelineState(); ComPtr<ID3D12PipelineState> GetPipelineState();
private: private:
using RenderPipelineBase::RenderPipelineBase;
MaybeError Initialize(const RenderPipelineDescriptor* descriptor);
D3D12_INPUT_LAYOUT_DESC ComputeInputLayout( D3D12_INPUT_LAYOUT_DESC ComputeInputLayout(
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors); std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors);