mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-30 08:55:39 +00:00
This CL updates the clang format files to have a single shared format between Dawn and Tint. The major changes are tabs are 4 spaces, lines are 100 columns and namespaces are not indented. Bug: dawn:1339 Change-Id: I4208742c95643998d9fd14e77a9cc558071ded39 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/87603 Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
226 lines
8.9 KiB
C++
226 lines
8.9 KiB
C++
// Copyright 2021 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/IndirectDrawMetadata.h"
|
|
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
#include "dawn/common/Constants.h"
|
|
#include "dawn/common/RefCounted.h"
|
|
#include "dawn/native/IndirectDrawValidationEncoder.h"
|
|
#include "dawn/native/Limits.h"
|
|
#include "dawn/native/RenderBundle.h"
|
|
|
|
namespace dawn::native {
|
|
|
|
uint64_t ComputeMaxIndirectValidationBatchOffsetRange(const CombinedLimits& limits) {
|
|
return limits.v1.maxStorageBufferBindingSize - limits.v1.minStorageBufferOffsetAlignment -
|
|
kDrawIndexedIndirectSize;
|
|
}
|
|
|
|
IndirectDrawMetadata::IndexedIndirectBufferValidationInfo::IndexedIndirectBufferValidationInfo(
|
|
BufferBase* indirectBuffer)
|
|
: mIndirectBuffer(indirectBuffer) {}
|
|
|
|
void IndirectDrawMetadata::IndexedIndirectBufferValidationInfo::AddIndirectDraw(
|
|
uint32_t maxDrawCallsPerIndirectValidationBatch,
|
|
uint64_t maxBatchOffsetRange,
|
|
IndirectDraw draw) {
|
|
const uint64_t newOffset = draw.inputBufferOffset;
|
|
auto it = mBatches.begin();
|
|
while (it != mBatches.end()) {
|
|
IndirectValidationBatch& batch = *it;
|
|
if (batch.draws.size() >= maxDrawCallsPerIndirectValidationBatch) {
|
|
// This batch is full. If its minOffset is to the right of the new offset, we can
|
|
// just insert a new batch here.
|
|
if (newOffset < batch.minOffset) {
|
|
break;
|
|
}
|
|
|
|
// Otherwise keep looking.
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
if (newOffset >= batch.minOffset && newOffset <= batch.maxOffset) {
|
|
batch.draws.push_back(std::move(draw));
|
|
return;
|
|
}
|
|
|
|
if (newOffset < batch.minOffset && batch.maxOffset - newOffset <= maxBatchOffsetRange) {
|
|
// We can extend this batch to the left in order to fit the new offset.
|
|
batch.minOffset = newOffset;
|
|
batch.draws.push_back(std::move(draw));
|
|
return;
|
|
}
|
|
|
|
if (newOffset > batch.maxOffset && newOffset - batch.minOffset <= maxBatchOffsetRange) {
|
|
// We can extend this batch to the right in order to fit the new offset.
|
|
batch.maxOffset = newOffset;
|
|
batch.draws.push_back(std::move(draw));
|
|
return;
|
|
}
|
|
|
|
if (newOffset < batch.minOffset) {
|
|
// We want to insert a new batch just before this one.
|
|
break;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
IndirectValidationBatch newBatch;
|
|
newBatch.minOffset = newOffset;
|
|
newBatch.maxOffset = newOffset;
|
|
newBatch.draws.push_back(std::move(draw));
|
|
|
|
mBatches.insert(it, std::move(newBatch));
|
|
}
|
|
|
|
void IndirectDrawMetadata::IndexedIndirectBufferValidationInfo::AddBatch(
|
|
uint32_t maxDrawCallsPerIndirectValidationBatch,
|
|
uint64_t maxBatchOffsetRange,
|
|
const IndirectValidationBatch& newBatch) {
|
|
auto it = mBatches.begin();
|
|
while (it != mBatches.end()) {
|
|
IndirectValidationBatch& batch = *it;
|
|
uint64_t min = std::min(newBatch.minOffset, batch.minOffset);
|
|
uint64_t max = std::max(newBatch.maxOffset, batch.maxOffset);
|
|
if (max - min <= maxBatchOffsetRange &&
|
|
batch.draws.size() + newBatch.draws.size() <= maxDrawCallsPerIndirectValidationBatch) {
|
|
// This batch fits within the limits of an existing batch. Merge it.
|
|
batch.minOffset = min;
|
|
batch.maxOffset = max;
|
|
batch.draws.insert(batch.draws.end(), newBatch.draws.begin(), newBatch.draws.end());
|
|
return;
|
|
}
|
|
|
|
if (newBatch.minOffset < batch.minOffset) {
|
|
break;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
mBatches.push_back(newBatch);
|
|
}
|
|
|
|
const std::vector<IndirectDrawMetadata::IndirectValidationBatch>&
|
|
IndirectDrawMetadata::IndexedIndirectBufferValidationInfo::GetBatches() const {
|
|
return mBatches;
|
|
}
|
|
|
|
IndirectDrawMetadata::IndirectDrawMetadata(const CombinedLimits& limits)
|
|
: mMaxBatchOffsetRange(ComputeMaxIndirectValidationBatchOffsetRange(limits)),
|
|
mMaxDrawCallsPerBatch(ComputeMaxDrawCallsPerIndirectValidationBatch(limits)) {}
|
|
|
|
IndirectDrawMetadata::~IndirectDrawMetadata() = default;
|
|
|
|
IndirectDrawMetadata::IndirectDrawMetadata(IndirectDrawMetadata&&) = default;
|
|
|
|
IndirectDrawMetadata& IndirectDrawMetadata::operator=(IndirectDrawMetadata&&) = default;
|
|
|
|
IndirectDrawMetadata::IndexedIndirectBufferValidationInfoMap*
|
|
IndirectDrawMetadata::GetIndexedIndirectBufferValidationInfo() {
|
|
return &mIndexedIndirectBufferValidationInfo;
|
|
}
|
|
|
|
void IndirectDrawMetadata::AddBundle(RenderBundleBase* bundle) {
|
|
auto [_, inserted] = mAddedBundles.insert(bundle);
|
|
if (!inserted) {
|
|
return;
|
|
}
|
|
|
|
for (const auto& [config, validationInfo] :
|
|
bundle->GetIndirectDrawMetadata().mIndexedIndirectBufferValidationInfo) {
|
|
auto it = mIndexedIndirectBufferValidationInfo.lower_bound(config);
|
|
if (it != mIndexedIndirectBufferValidationInfo.end() && it->first == config) {
|
|
// We already have batches for the same config. Merge the new ones in.
|
|
for (const IndirectValidationBatch& batch : validationInfo.GetBatches()) {
|
|
it->second.AddBatch(mMaxDrawCallsPerBatch, mMaxBatchOffsetRange, batch);
|
|
}
|
|
} else {
|
|
mIndexedIndirectBufferValidationInfo.emplace_hint(it, config, validationInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
void IndirectDrawMetadata::AddIndexedIndirectDraw(wgpu::IndexFormat indexFormat,
|
|
uint64_t indexBufferSize,
|
|
BufferBase* indirectBuffer,
|
|
uint64_t indirectOffset,
|
|
bool duplicateBaseVertexInstance,
|
|
DrawIndexedIndirectCmd* cmd) {
|
|
uint64_t numIndexBufferElements;
|
|
switch (indexFormat) {
|
|
case wgpu::IndexFormat::Uint16:
|
|
numIndexBufferElements = indexBufferSize / 2;
|
|
break;
|
|
case wgpu::IndexFormat::Uint32:
|
|
numIndexBufferElements = indexBufferSize / 4;
|
|
break;
|
|
case wgpu::IndexFormat::Undefined:
|
|
UNREACHABLE();
|
|
}
|
|
|
|
const IndexedIndirectConfig config = {indirectBuffer, numIndexBufferElements,
|
|
duplicateBaseVertexInstance, DrawType::Indexed};
|
|
auto it = mIndexedIndirectBufferValidationInfo.find(config);
|
|
if (it == mIndexedIndirectBufferValidationInfo.end()) {
|
|
auto result = mIndexedIndirectBufferValidationInfo.emplace(
|
|
config, IndexedIndirectBufferValidationInfo(indirectBuffer));
|
|
it = result.first;
|
|
}
|
|
|
|
IndirectDraw draw{};
|
|
draw.inputBufferOffset = indirectOffset;
|
|
draw.cmd = cmd;
|
|
it->second.AddIndirectDraw(mMaxDrawCallsPerBatch, mMaxBatchOffsetRange, draw);
|
|
}
|
|
|
|
void IndirectDrawMetadata::AddIndirectDraw(BufferBase* indirectBuffer,
|
|
uint64_t indirectOffset,
|
|
bool duplicateBaseVertexInstance,
|
|
DrawIndirectCmd* cmd) {
|
|
const IndexedIndirectConfig config = {indirectBuffer, 0, duplicateBaseVertexInstance,
|
|
DrawType::NonIndexed};
|
|
auto it = mIndexedIndirectBufferValidationInfo.find(config);
|
|
if (it == mIndexedIndirectBufferValidationInfo.end()) {
|
|
auto result = mIndexedIndirectBufferValidationInfo.emplace(
|
|
config, IndexedIndirectBufferValidationInfo(indirectBuffer));
|
|
it = result.first;
|
|
}
|
|
|
|
IndirectDraw draw{};
|
|
draw.inputBufferOffset = indirectOffset;
|
|
draw.cmd = cmd;
|
|
it->second.AddIndirectDraw(mMaxDrawCallsPerBatch, mMaxBatchOffsetRange, draw);
|
|
}
|
|
|
|
bool IndirectDrawMetadata::IndexedIndirectConfig::operator<(
|
|
const IndexedIndirectConfig& other) const {
|
|
return std::tie(inputIndirectBuffer, numIndexBufferElements, duplicateBaseVertexInstance,
|
|
drawType) < std::tie(other.inputIndirectBuffer, other.numIndexBufferElements,
|
|
other.duplicateBaseVertexInstance, other.drawType);
|
|
}
|
|
|
|
bool IndirectDrawMetadata::IndexedIndirectConfig::operator==(
|
|
const IndexedIndirectConfig& other) const {
|
|
return std::tie(inputIndirectBuffer, numIndexBufferElements, duplicateBaseVertexInstance,
|
|
drawType) == std::tie(other.inputIndirectBuffer, other.numIndexBufferElements,
|
|
other.duplicateBaseVertexInstance, other.drawType);
|
|
}
|
|
|
|
} // namespace dawn::native
|