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:
parent
c7d535bd72
commit
f3d50baf85
2
BUILD.gn
2
BUILD.gn
|
@ -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",
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue