blob: b97e317abb0fda8a62adbaa0d04c46f5d439b60c [file] [log] [blame]
Austin Engfde94902019-07-24 18:15:24 +00001// Copyright 2019 The Dawn Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef DAWNNATIVE_ENCODINGCONTEXT_H_
16#define DAWNNATIVE_ENCODINGCONTEXT_H_
17
18#include "dawn_native/CommandAllocator.h"
19#include "dawn_native/Error.h"
20#include "dawn_native/ErrorData.h"
Austin Eng4b0b7a52019-11-21 22:09:41 +000021#include "dawn_native/PassResourceUsageTracker.h"
Austin Engcb0cb652019-08-27 21:41:56 +000022#include "dawn_native/dawn_platform.h"
Austin Engfde94902019-07-24 18:15:24 +000023
24#include <string>
25
26namespace dawn_native {
27
Austin Engfde94902019-07-24 18:15:24 +000028 class DeviceBase;
Austin Eng4b0b7a52019-11-21 22:09:41 +000029 class ObjectBase;
Austin Engfde94902019-07-24 18:15:24 +000030
31 // Base class for allocating/iterating commands.
32 // It performs error tracking as well as encoding state for render/compute passes.
33 class EncodingContext {
34 public:
35 EncodingContext(DeviceBase* device, const ObjectBase* initialEncoder);
36 ~EncodingContext();
37
38 CommandIterator AcquireCommands();
39 CommandIterator* GetIterator();
40
41 // Functions to handle encoder errors
Corentin Wallezd98b3072021-05-05 17:37:43 +000042 void HandleError(std::unique_ptr<ErrorData> error);
Austin Engfde94902019-07-24 18:15:24 +000043
44 inline bool ConsumedError(MaybeError maybeError) {
45 if (DAWN_UNLIKELY(maybeError.IsError())) {
Corentin Wallezd98b3072021-05-05 17:37:43 +000046 HandleError(maybeError.AcquireError());
Austin Engfde94902019-07-24 18:15:24 +000047 return true;
48 }
49 return false;
50 }
51
Austin Eng464aaeb2020-11-14 01:24:03 +000052 inline bool CheckCurrentEncoder(const ObjectBase* encoder) {
Austin Engfde94902019-07-24 18:15:24 +000053 if (DAWN_UNLIKELY(encoder != mCurrentEncoder)) {
54 if (mCurrentEncoder != mTopLevelEncoder) {
55 // The top level encoder was used when a pass encoder was current.
Corentin Wallezd98b3072021-05-05 17:37:43 +000056 HandleError(DAWN_VALIDATION_ERROR("Command cannot be recorded inside a pass"));
Austin Engfde94902019-07-24 18:15:24 +000057 } else {
Corentin Wallezd98b3072021-05-05 17:37:43 +000058 HandleError(DAWN_VALIDATION_ERROR(
59 "Recording in an error or already ended pass encoder"));
Austin Engfde94902019-07-24 18:15:24 +000060 }
61 return false;
62 }
Austin Eng464aaeb2020-11-14 01:24:03 +000063 return true;
64 }
65
66 template <typename EncodeFunction>
67 inline bool TryEncode(const ObjectBase* encoder, EncodeFunction&& encodeFunction) {
68 if (!CheckCurrentEncoder(encoder)) {
69 return false;
70 }
Austin Engfde94902019-07-24 18:15:24 +000071 ASSERT(!mWasMovedToIterator);
72 return !ConsumedError(encodeFunction(&mAllocator));
73 }
74
75 // Functions to set current encoder state
76 void EnterPass(const ObjectBase* passEncoder);
Corentin Wallezec7ea6a2021-05-05 19:55:23 +000077 void ExitPass(const ObjectBase* passEncoder, RenderPassResourceUsage usages);
78 void ExitPass(const ObjectBase* passEncoder, ComputePassResourceUsage usages);
Austin Engfde94902019-07-24 18:15:24 +000079 MaybeError Finish();
80
Corentin Wallez2dd2d672021-05-05 15:41:13 +000081 const RenderPassUsages& GetRenderPassUsages() const;
82 const ComputePassUsages& GetComputePassUsages() const;
83 RenderPassUsages AcquireRenderPassUsages();
84 ComputePassUsages AcquireComputePassUsages();
Austin Eng4b0b7a52019-11-21 22:09:41 +000085
Austin Engfde94902019-07-24 18:15:24 +000086 private:
87 bool IsFinished() const;
Austin Eng4b0b7a52019-11-21 22:09:41 +000088 void MoveToIterator();
Austin Engfde94902019-07-24 18:15:24 +000089
90 DeviceBase* mDevice;
91
92 // There can only be two levels of encoders. Top-level and render/compute pass.
93 // The top level encoder is the encoder the EncodingContext is created with.
94 // It doubles as flag to check if encoding has been Finished.
95 const ObjectBase* mTopLevelEncoder;
96 // The current encoder must be the same as the encoder provided to TryEncode,
97 // otherwise an error is produced. It may be nullptr if the EncodingContext is an error.
98 // The current encoder changes with Enter/ExitPass which should be called by
99 // CommandEncoder::Begin/EndPass.
100 const ObjectBase* mCurrentEncoder;
101
Corentin Wallez2dd2d672021-05-05 15:41:13 +0000102 RenderPassUsages mRenderPassUsages;
103 bool mWereRenderPassUsagesAcquired = false;
104 ComputePassUsages mComputePassUsages;
105 bool mWereComputePassUsagesAcquired = false;
Austin Eng4b0b7a52019-11-21 22:09:41 +0000106
Austin Engfde94902019-07-24 18:15:24 +0000107 CommandAllocator mAllocator;
108 CommandIterator mIterator;
109 bool mWasMovedToIterator = false;
110 bool mWereCommandsAcquired = false;
111
Corentin Wallezd98b3072021-05-05 17:37:43 +0000112 std::unique_ptr<ErrorData> mError;
Austin Engfde94902019-07-24 18:15:24 +0000113 };
114
115} // namespace dawn_native
116
117#endif // DAWNNATIVE_ENCODINGCONTEXT_H_