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/ComputePipelineD3D12.cpp",
|
||||
"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.h",
|
||||
"src/dawn_native/d3d12/DescriptorHeapAllocator.cpp",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "common/Constants.h"
|
||||
#include "common/Math.h"
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
@ -217,8 +218,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
|
||||
mWrittenMappedRange = {0, GetSize()};
|
||||
ASSERT_SUCCESS(GetD3D12Resource()->Map(0, &mWrittenMappedRange,
|
||||
reinterpret_cast<void**>(mappedPointer)));
|
||||
DAWN_TRY(CheckHRESULT(GetD3D12Resource()->Map(0, &mWrittenMappedRange,
|
||||
reinterpret_cast<void**>(mappedPointer)),
|
||||
"D3D12 map at creation"));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -226,7 +228,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
mWrittenMappedRange = {};
|
||||
D3D12_RANGE readRange = {0, GetSize()};
|
||||
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
|
||||
// writes available when the fence is passed.
|
||||
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
|
||||
|
@ -237,8 +241,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
MaybeError Buffer::MapWriteAsyncImpl(uint32_t serial) {
|
||||
mWrittenMappedRange = {0, GetSize()};
|
||||
char* data = nullptr;
|
||||
ASSERT_SUCCESS(
|
||||
GetD3D12Resource()->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(&data)));
|
||||
DAWN_TRY(CheckHRESULT(
|
||||
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
|
||||
// writes available on queue submission.
|
||||
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "dawn_native/d3d12/CommandAllocatorManager.h"
|
||||
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
|
@ -26,12 +27,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 (mFreeAllocators.none()) {
|
||||
const uint64_t firstSerial = mInFlightCommandAllocators.FirstSerial();
|
||||
device->WaitForSerial(firstSerial);
|
||||
Tick(firstSerial);
|
||||
DAWN_TRY(device->WaitForSerial(firstSerial));
|
||||
DAWN_TRY(Tick(firstSerial));
|
||||
}
|
||||
|
||||
ASSERT(mFreeAllocators.any());
|
||||
|
@ -42,8 +43,10 @@ namespace dawn_native { namespace d3d12 {
|
|||
if (firstFreeIndex >= mAllocatorCount) {
|
||||
ASSERT(firstFreeIndex == mAllocatorCount);
|
||||
mAllocatorCount++;
|
||||
ASSERT_SUCCESS(device->GetD3D12Device()->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex])));
|
||||
DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex])),
|
||||
"D3D12 create command allocator"));
|
||||
}
|
||||
|
||||
// Mark the command allocator as used
|
||||
|
@ -53,17 +56,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
// ExecuteCommandLists
|
||||
mInFlightCommandAllocators.Enqueue({mCommandAllocators[firstFreeIndex], firstFreeIndex},
|
||||
device->GetPendingCommandSerial());
|
||||
|
||||
return mCommandAllocators[firstFreeIndex];
|
||||
return mCommandAllocators[firstFreeIndex].Get();
|
||||
}
|
||||
|
||||
void CommandAllocatorManager::Tick(uint64_t lastCompletedSerial) {
|
||||
MaybeError CommandAllocatorManager::Tick(uint64_t lastCompletedSerial) {
|
||||
// Reset all command allocators that are no longer in flight
|
||||
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);
|
||||
}
|
||||
mInFlightCommandAllocators.ClearUpTo(lastCompletedSerial);
|
||||
return {};
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
#include "common/SerialQueue.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
#include <bitset>
|
||||
|
||||
|
@ -31,8 +32,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
// 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
|
||||
ComPtr<ID3D12CommandAllocator> ReserveCommandAllocator();
|
||||
void Tick(uint64_t lastCompletedSerial);
|
||||
ResultOrError<ID3D12CommandAllocator*> ReserveCommandAllocator();
|
||||
MaybeError Tick(uint64_t lastCompletedSerial);
|
||||
|
||||
private:
|
||||
Device* device;
|
||||
|
|
|
@ -13,28 +13,28 @@
|
|||
// limitations under the License.
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/CommandAllocatorManager.h"
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
MaybeError CommandRecordingContext::Open(ID3D12Device* d3d12Device,
|
||||
CommandAllocatorManager* commandAllocationManager) {
|
||||
ASSERT(!IsOpen());
|
||||
ID3D12CommandAllocator* commandAllocator;
|
||||
DAWN_TRY_ASSIGN(commandAllocator, commandAllocationManager->ReserveCommandAllocator());
|
||||
if (mD3d12CommandList != nullptr) {
|
||||
const HRESULT hr = mD3d12CommandList->Reset(
|
||||
commandAllocationManager->ReserveCommandAllocator().Get(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
MaybeError error = CheckHRESULT(mD3d12CommandList->Reset(commandAllocator, nullptr),
|
||||
"D3D12 resetting command list");
|
||||
if (error.IsError()) {
|
||||
mD3d12CommandList.Reset();
|
||||
return DAWN_DEVICE_LOST_ERROR("Error resetting command list.");
|
||||
DAWN_TRY(std::move(error));
|
||||
}
|
||||
} else {
|
||||
ComPtr<ID3D12GraphicsCommandList> d3d12GraphicsCommandList;
|
||||
const HRESULT hr = d3d12Device->CreateCommandList(
|
||||
0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
commandAllocationManager->ReserveCommandAllocator().Get(), nullptr,
|
||||
IID_PPV_ARGS(&d3d12GraphicsCommandList));
|
||||
if (FAILED(hr)) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Error creating a direct command list.");
|
||||
}
|
||||
DAWN_TRY(CheckHRESULT(
|
||||
d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator,
|
||||
nullptr, IID_PPV_ARGS(&d3d12GraphicsCommandList)),
|
||||
"D3D12 creating direct command list"));
|
||||
mD3d12CommandList = std::move(d3d12GraphicsCommandList);
|
||||
}
|
||||
|
||||
|
@ -46,10 +46,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
ResultOrError<ID3D12GraphicsCommandList*> CommandRecordingContext::Close() {
|
||||
ASSERT(IsOpen());
|
||||
mIsOpen = false;
|
||||
const HRESULT hr = mD3d12CommandList->Close();
|
||||
if (FAILED(hr)) {
|
||||
MaybeError error =
|
||||
CheckHRESULT(mD3d12CommandList->Close(), "D3D12 closing pending command list");
|
||||
if (error.IsError()) {
|
||||
mD3d12CommandList.Reset();
|
||||
return DAWN_DEVICE_LOST_ERROR("Error closing pending command list.");
|
||||
DAWN_TRY(std::move(error));
|
||||
}
|
||||
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/CommandBufferD3D12.h"
|
||||
#include "dawn_native/d3d12/ComputePipelineD3D12.h"
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
|
||||
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/PlatformFunctions.h"
|
||||
|
@ -56,10 +57,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
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);
|
||||
ASSERT(mFenceEvent != nullptr);
|
||||
|
||||
|
@ -70,7 +75,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
mResourceAllocator = std::make_unique<ResourceAllocator>(this);
|
||||
mResourceAllocatorManager = std::make_unique<ResourceAllocatorManager>(this);
|
||||
|
||||
NextSerial();
|
||||
DAWN_TRY(NextSerial());
|
||||
|
||||
// Initialize indirect commands
|
||||
D3D12_INDIRECT_ARGUMENT_DESC argumentDesc = {};
|
||||
|
@ -103,8 +108,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
// Immediately forget about all pending commands
|
||||
mPendingCommands.Release();
|
||||
|
||||
NextSerial();
|
||||
WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing
|
||||
ConsumedError(NextSerial());
|
||||
// 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
|
||||
// continue shutting down in an orderly fashion.
|
||||
|
@ -207,27 +213,29 @@ namespace dawn_native { namespace d3d12 {
|
|||
mDynamicUploader->Deallocate(mCompletedSerial);
|
||||
|
||||
mResourceAllocator->Tick(mCompletedSerial);
|
||||
mCommandAllocatorManager->Tick(mCompletedSerial);
|
||||
DAWN_TRY(mCommandAllocatorManager->Tick(mCompletedSerial));
|
||||
mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
|
||||
mMapRequestTracker->Tick(mCompletedSerial);
|
||||
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
||||
DAWN_TRY(ExecuteCommandContext(nullptr));
|
||||
NextSerial();
|
||||
|
||||
DAWN_TRY(NextSerial());
|
||||
return {};
|
||||
}
|
||||
|
||||
void Device::NextSerial() {
|
||||
MaybeError Device::NextSerial() {
|
||||
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();
|
||||
if (mCompletedSerial < serial) {
|
||||
ASSERT_SUCCESS(mFence->SetEventOnCompletion(serial, mFenceEvent));
|
||||
DAWN_TRY(CheckHRESULT(mFence->SetEventOnCompletion(serial, mFenceEvent),
|
||||
"D3D12 set event on completion"));
|
||||
WaitForSingleObject(mFenceEvent, INFINITE);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) {
|
||||
|
@ -279,14 +287,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -73,8 +73,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
ResultOrError<CommandRecordingContext*> GetPendingCommandContext();
|
||||
Serial GetPendingCommandSerial() const override;
|
||||
|
||||
void NextSerial();
|
||||
void WaitForSerial(Serial serial);
|
||||
MaybeError NextSerial();
|
||||
MaybeError WaitForSerial(Serial serial);
|
||||
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
ASSERT_SUCCESS(mSwapChain->Present(1, 0));
|
||||
// TODO(cwallez@chromium.org): Make the serial ticking implicit.
|
||||
mDevice->NextSerial();
|
||||
ASSERT(mDevice->NextSerial().IsSuccess());
|
||||
|
||||
mBufferSerials[mCurrentBuffer] = mDevice->GetPendingCommandSerial();
|
||||
return DAWN_SWAP_CHAIN_NO_ERROR;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "common/Assert.h"
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/PlatformFunctions.h"
|
||||
|
||||
|
@ -54,8 +55,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
} // anonymous namespace
|
||||
|
||||
PipelineLayout::PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor)
|
||||
: PipelineLayoutBase(device, descriptor) {
|
||||
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() {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
D3D12_ROOT_PARAMETER rootParameters[kMaxBindGroups * 2 + kMaxDynamicBufferCount];
|
||||
|
||||
// A root parameter is one of these types
|
||||
|
@ -148,11 +158,15 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
ComPtr<ID3DBlob> signature;
|
||||
ComPtr<ID3DBlob> error;
|
||||
ASSERT_SUCCESS(device->GetFunctions()->d3d12SerializeRootSignature(
|
||||
&rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
|
||||
ASSERT_SUCCESS(device->GetD3D12Device()->CreateRootSignature(
|
||||
0, signature->GetBufferPointer(), signature->GetBufferSize(),
|
||||
IID_PPV_ARGS(&mRootSignature)));
|
||||
DAWN_TRY(CheckHRESULT(
|
||||
device->GetFunctions()->d3d12SerializeRootSignature(
|
||||
&rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error),
|
||||
"D3D12 serialize root signature"));
|
||||
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 {
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
class PipelineLayout : public PipelineLayoutBase {
|
||||
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 GetSamplerRootParameterIndex(uint32_t group) const;
|
||||
|
@ -36,6 +37,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
ComPtr<ID3D12RootSignature> GetRootSignature() const;
|
||||
|
||||
private:
|
||||
using PipelineLayoutBase::PipelineLayoutBase;
|
||||
MaybeError Initialize();
|
||||
std::array<uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo;
|
||||
std::array<uint32_t, kMaxBindGroups> mSamplerRootParameterInfo;
|
||||
std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dawn_native/d3d12/QueueD3D12.h"
|
||||
|
||||
#include "dawn_native/d3d12/CommandBufferD3D12.h"
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
@ -35,7 +36,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
DAWN_TRY(device->ExecuteCommandContext(&mCommandContext));
|
||||
|
||||
device->NextSerial();
|
||||
DAWN_TRY(device->NextSerial());
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "dawn_native/d3d12/D3D12Error.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/PlatformFunctions.h"
|
||||
|
@ -288,9 +289,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor),
|
||||
mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())) {
|
||||
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());
|
||||
uint32_t compileFlags = 0;
|
||||
#if defined(_DEBUG)
|
||||
// Enable better shader debugging with the graphics debugging tools.
|
||||
|
@ -391,8 +400,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
descriptorD3D12.SampleDesc.Count = GetSampleCount();
|
||||
descriptorD3D12.SampleDesc.Quality = 0;
|
||||
|
||||
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(
|
||||
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)));
|
||||
mD3d12PrimitiveTopology = D3D12PrimitiveTopology(GetPrimitiveTopology());
|
||||
|
||||
DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateGraphicsPipelineState(
|
||||
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)),
|
||||
"D3D12 create graphics pipeline state"));
|
||||
return {};
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
|
|
|
@ -25,13 +25,16 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
static ResultOrError<RenderPipeline*> Create(Device* device,
|
||||
const RenderPipelineDescriptor* descriptor);
|
||||
~RenderPipeline();
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const;
|
||||
ComPtr<ID3D12PipelineState> GetPipelineState();
|
||||
|
||||
private:
|
||||
using RenderPipelineBase::RenderPipelineBase;
|
||||
MaybeError Initialize(const RenderPipelineDescriptor* descriptor);
|
||||
D3D12_INPUT_LAYOUT_DESC ComputeInputLayout(
|
||||
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors);
|
||||
|
||||
|
|
Loading…
Reference in New Issue