mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-06 04:05:40 +00:00
Done with changes to Error.h and the following command: git grep -l DAWN_FORMAT_VALIDATION_ERROR | xargs sed -i "" "s/DAWN_FORMAT_VALIDATION_ERROR/DAWN_VALIDATION_ERROR/" then fixing compilation errors in ErrorTests.cpp, Pipeline.cpp and CommandEncoder.cpp. Bug: dawn:563 Change-Id: I081a514d662e81f4842b6d7fadfcea67c12720d6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100468 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
185 lines
6.8 KiB
C++
185 lines
6.8 KiB
C++
// 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 SRC_DAWN_NATIVE_ENCODINGCONTEXT_H_
|
|
#define SRC_DAWN_NATIVE_ENCODINGCONTEXT_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "dawn/native/CommandAllocator.h"
|
|
#include "dawn/native/Error.h"
|
|
#include "dawn/native/ErrorData.h"
|
|
#include "dawn/native/IndirectDrawMetadata.h"
|
|
#include "dawn/native/PassResourceUsageTracker.h"
|
|
#include "dawn/native/dawn_platform.h"
|
|
|
|
namespace dawn::native {
|
|
|
|
class CommandEncoder;
|
|
class DeviceBase;
|
|
class ApiObjectBase;
|
|
|
|
// Base class for allocating/iterating commands.
|
|
// It performs error tracking as well as encoding state for render/compute passes.
|
|
class EncodingContext {
|
|
public:
|
|
EncodingContext(DeviceBase* device, const ApiObjectBase* initialEncoder);
|
|
~EncodingContext();
|
|
|
|
// Marks the encoding context as destroyed so that any future encodes will fail, and all
|
|
// encoded commands are released.
|
|
void Destroy();
|
|
|
|
CommandIterator AcquireCommands();
|
|
CommandIterator* GetIterator();
|
|
|
|
// Functions to handle encoder errors
|
|
void HandleError(std::unique_ptr<ErrorData> error);
|
|
|
|
inline bool ConsumedError(MaybeError maybeError) {
|
|
if (DAWN_UNLIKELY(maybeError.IsError())) {
|
|
HandleError(maybeError.AcquireError());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template <typename... Args>
|
|
inline bool ConsumedError(MaybeError maybeError, const char* formatStr, const Args&... args) {
|
|
if (DAWN_UNLIKELY(maybeError.IsError())) {
|
|
std::unique_ptr<ErrorData> error = maybeError.AcquireError();
|
|
if (error->GetType() == InternalErrorType::Validation) {
|
|
std::string out;
|
|
absl::UntypedFormatSpec format(formatStr);
|
|
if (absl::FormatUntyped(&out, format, {absl::FormatArg(args)...})) {
|
|
error->AppendContext(std::move(out));
|
|
} else {
|
|
error->AppendContext(
|
|
absl::StrFormat("[Failed to format error message: \"%s\"].", formatStr));
|
|
}
|
|
}
|
|
HandleError(std::move(error));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline bool CheckCurrentEncoder(const ApiObjectBase* encoder) {
|
|
if (mDestroyed) {
|
|
HandleError(DAWN_VALIDATION_ERROR("Recording in a destroyed %s.", mCurrentEncoder));
|
|
return false;
|
|
}
|
|
if (DAWN_UNLIKELY(encoder != mCurrentEncoder)) {
|
|
if (mCurrentEncoder != mTopLevelEncoder) {
|
|
// The top level encoder was used when a pass encoder was current.
|
|
HandleError(DAWN_VALIDATION_ERROR("Command cannot be recorded while %s is active.",
|
|
mCurrentEncoder));
|
|
} else {
|
|
HandleError(
|
|
DAWN_VALIDATION_ERROR("Recording in an error or already ended %s.", encoder));
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <typename EncodeFunction>
|
|
inline bool TryEncode(const ApiObjectBase* encoder, EncodeFunction&& encodeFunction) {
|
|
if (!CheckCurrentEncoder(encoder)) {
|
|
return false;
|
|
}
|
|
ASSERT(!mWasMovedToIterator);
|
|
return !ConsumedError(encodeFunction(&mPendingCommands));
|
|
}
|
|
|
|
template <typename EncodeFunction, typename... Args>
|
|
inline bool TryEncode(const ApiObjectBase* encoder,
|
|
EncodeFunction&& encodeFunction,
|
|
const char* formatStr,
|
|
const Args&... args) {
|
|
if (!CheckCurrentEncoder(encoder)) {
|
|
return false;
|
|
}
|
|
ASSERT(!mWasMovedToIterator);
|
|
return !ConsumedError(encodeFunction(&mPendingCommands), formatStr, args...);
|
|
}
|
|
|
|
// Must be called prior to encoding a BeginRenderPassCmd. Note that it's OK to call this
|
|
// and then not actually call EnterPass+ExitRenderPass, for example if some other pass setup
|
|
// failed validation before the BeginRenderPassCmd could be encoded.
|
|
void WillBeginRenderPass();
|
|
|
|
// Functions to set current encoder state
|
|
void EnterPass(const ApiObjectBase* passEncoder);
|
|
MaybeError ExitRenderPass(const ApiObjectBase* passEncoder,
|
|
RenderPassResourceUsageTracker usageTracker,
|
|
CommandEncoder* commandEncoder,
|
|
IndirectDrawMetadata indirectDrawMetadata);
|
|
void ExitComputePass(const ApiObjectBase* passEncoder, ComputePassResourceUsage usages);
|
|
MaybeError Finish();
|
|
|
|
// Called when a pass encoder is deleted. Provides an opportunity to clean up if it's the
|
|
// mCurrentEncoder.
|
|
void EnsurePassExited(const ApiObjectBase* passEncoder);
|
|
|
|
const RenderPassUsages& GetRenderPassUsages() const;
|
|
const ComputePassUsages& GetComputePassUsages() const;
|
|
RenderPassUsages AcquireRenderPassUsages();
|
|
ComputePassUsages AcquireComputePassUsages();
|
|
|
|
void PushDebugGroupLabel(const char* groupLabel);
|
|
void PopDebugGroupLabel();
|
|
|
|
private:
|
|
void CommitCommands(CommandAllocator allocator);
|
|
|
|
bool IsFinished() const;
|
|
void MoveToIterator();
|
|
|
|
DeviceBase* mDevice;
|
|
|
|
// There can only be two levels of encoders. Top-level and render/compute pass.
|
|
// The top level encoder is the encoder the EncodingContext is created with.
|
|
// It doubles as flag to check if encoding has been Finished.
|
|
const ApiObjectBase* mTopLevelEncoder;
|
|
// The current encoder must be the same as the encoder provided to TryEncode,
|
|
// otherwise an error is produced. It may be nullptr if the EncodingContext is an error.
|
|
// The current encoder changes with Enter/ExitPass which should be called by
|
|
// CommandEncoder::Begin/EndPass.
|
|
const ApiObjectBase* mCurrentEncoder;
|
|
|
|
RenderPassUsages mRenderPassUsages;
|
|
bool mWereRenderPassUsagesAcquired = false;
|
|
ComputePassUsages mComputePassUsages;
|
|
bool mWereComputePassUsagesAcquired = false;
|
|
|
|
CommandAllocator mPendingCommands;
|
|
|
|
std::vector<CommandAllocator> mAllocators;
|
|
CommandIterator mIterator;
|
|
bool mWasMovedToIterator = false;
|
|
bool mWereCommandsAcquired = false;
|
|
bool mDestroyed = false;
|
|
|
|
std::unique_ptr<ErrorData> mError;
|
|
std::vector<std::string> mDebugGroupLabels;
|
|
};
|
|
|
|
} // namespace dawn::native
|
|
|
|
#endif // SRC_DAWN_NATIVE_ENCODINGCONTEXT_H_
|