mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-04 05:31:27 +00:00
This is a reland of 6d9e4f8076b645c557453f4b566bf9c38b4a51eb Now that the Chromium-side API change has landed, this CL can land. Original change's description: > Add ComparisonSampler binding type and validation tests > > Bug: dawn:367 > Change-Id: Iba1d3d03f6247a356b6f3fabfe7a7ba3c0753171 > Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/18423 > Reviewed-by: Austin Eng <enga@chromium.org> > Commit-Queue: Austin Eng <enga@chromium.org> Bug: dawn:367 TBR=cwallez@chromium.org,kainino@chromium.org Change-Id: I325d096e7ce092d17833429c3f54ef7c71189739 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20045 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
206 lines
9.2 KiB
C++
206 lines
9.2 KiB
C++
// Copyright 2017 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/BindGroupLayoutD3D12.h"
|
|
|
|
#include "common/BitSetIterator.h"
|
|
#include "dawn_native/d3d12/BindGroupD3D12.h"
|
|
#include "dawn_native/d3d12/DeviceD3D12.h"
|
|
#include "dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h"
|
|
|
|
namespace dawn_native { namespace d3d12 {
|
|
namespace {
|
|
BindGroupLayout::DescriptorType WGPUBindingTypeToDescriptorType(
|
|
wgpu::BindingType bindingType) {
|
|
switch (bindingType) {
|
|
case wgpu::BindingType::UniformBuffer:
|
|
return BindGroupLayout::DescriptorType::CBV;
|
|
case wgpu::BindingType::StorageBuffer:
|
|
case wgpu::BindingType::WriteonlyStorageTexture:
|
|
return BindGroupLayout::DescriptorType::UAV;
|
|
case wgpu::BindingType::SampledTexture:
|
|
case wgpu::BindingType::ReadonlyStorageBuffer:
|
|
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
return BindGroupLayout::DescriptorType::SRV;
|
|
case wgpu::BindingType::Sampler:
|
|
case wgpu::BindingType::ComparisonSampler:
|
|
return BindGroupLayout::DescriptorType::Sampler;
|
|
case wgpu::BindingType::StorageTexture:
|
|
UNREACHABLE();
|
|
return BindGroupLayout::DescriptorType::UAV;
|
|
}
|
|
}
|
|
} // anonymous namespace
|
|
|
|
BindGroupLayout::BindGroupLayout(Device* device, const BindGroupLayoutDescriptor* descriptor)
|
|
: BindGroupLayoutBase(device, descriptor),
|
|
mDescriptorCounts{},
|
|
mBindGroupAllocator(MakeFrontendBindGroupAllocator<BindGroup>(4096)) {
|
|
for (BindingIndex bindingIndex = GetDynamicBufferCount(); bindingIndex < GetBindingCount();
|
|
++bindingIndex) {
|
|
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
|
|
|
|
// For dynamic resources, Dawn uses root descriptor in D3D12 backend.
|
|
// So there is no need to allocate the descriptor from descriptor heap.
|
|
// This loop starts after the dynamic buffer indices to skip counting
|
|
// dynamic resources in calculating the size of the descriptor heap.
|
|
ASSERT(!bindingInfo.hasDynamicOffset);
|
|
|
|
DescriptorType descriptorType = WGPUBindingTypeToDescriptorType(bindingInfo.type);
|
|
mBindingOffsets[bindingIndex] = mDescriptorCounts[descriptorType]++;
|
|
}
|
|
|
|
auto SetDescriptorRange = [&](uint32_t index, uint32_t count, uint32_t* baseRegister,
|
|
D3D12_DESCRIPTOR_RANGE_TYPE type) -> bool {
|
|
if (count == 0) {
|
|
return false;
|
|
}
|
|
|
|
auto& range = mRanges[index];
|
|
range.RangeType = type;
|
|
range.NumDescriptors = count;
|
|
range.RegisterSpace = 0;
|
|
range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
range.BaseShaderRegister = *baseRegister;
|
|
*baseRegister += count;
|
|
// These ranges will be copied and range.BaseShaderRegister will be set in
|
|
// d3d12::PipelineLayout to account for bind group register offsets
|
|
return true;
|
|
};
|
|
|
|
uint32_t rangeIndex = 0;
|
|
uint32_t baseRegister = 0;
|
|
|
|
std::array<uint32_t, DescriptorType::Count> descriptorOffsets;
|
|
// Ranges 0-2 contain the CBV, UAV, and SRV ranges, if they exist, tightly packed
|
|
// Range 3 contains the Sampler range, if there is one
|
|
if (SetDescriptorRange(rangeIndex, mDescriptorCounts[CBV], &baseRegister,
|
|
D3D12_DESCRIPTOR_RANGE_TYPE_CBV)) {
|
|
descriptorOffsets[CBV] = mRanges[rangeIndex++].BaseShaderRegister;
|
|
}
|
|
if (SetDescriptorRange(rangeIndex, mDescriptorCounts[UAV], &baseRegister,
|
|
D3D12_DESCRIPTOR_RANGE_TYPE_UAV)) {
|
|
descriptorOffsets[UAV] = mRanges[rangeIndex++].BaseShaderRegister;
|
|
}
|
|
if (SetDescriptorRange(rangeIndex, mDescriptorCounts[SRV], &baseRegister,
|
|
D3D12_DESCRIPTOR_RANGE_TYPE_SRV)) {
|
|
descriptorOffsets[SRV] = mRanges[rangeIndex++].BaseShaderRegister;
|
|
}
|
|
uint32_t zero = 0;
|
|
SetDescriptorRange(Sampler, mDescriptorCounts[Sampler], &zero,
|
|
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER);
|
|
descriptorOffsets[Sampler] = 0;
|
|
|
|
for (BindingIndex bindingIndex = 0; bindingIndex < GetBindingCount(); ++bindingIndex) {
|
|
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
|
|
|
|
if (bindingInfo.hasDynamicOffset) {
|
|
// Dawn is using values in mBindingOffsets to decide register number in HLSL.
|
|
// Root descriptor needs to set this value to set correct register number in
|
|
// generated HLSL shader.
|
|
switch (bindingInfo.type) {
|
|
case wgpu::BindingType::UniformBuffer:
|
|
case wgpu::BindingType::StorageBuffer:
|
|
case wgpu::BindingType::ReadonlyStorageBuffer:
|
|
mBindingOffsets[bindingIndex] = baseRegister++;
|
|
break;
|
|
case wgpu::BindingType::SampledTexture:
|
|
case wgpu::BindingType::Sampler:
|
|
case wgpu::BindingType::ComparisonSampler:
|
|
case wgpu::BindingType::StorageTexture:
|
|
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
case wgpu::BindingType::WriteonlyStorageTexture:
|
|
UNREACHABLE();
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
|
|
DescriptorType descriptorType = WGPUBindingTypeToDescriptorType(bindingInfo.type);
|
|
mBindingOffsets[bindingIndex] += descriptorOffsets[descriptorType];
|
|
}
|
|
|
|
mViewAllocator = device->GetViewStagingDescriptorAllocator(GetCbvUavSrvDescriptorCount());
|
|
mSamplerAllocator =
|
|
device->GetSamplerStagingDescriptorAllocator(GetSamplerDescriptorCount());
|
|
}
|
|
|
|
ResultOrError<BindGroup*> BindGroupLayout::AllocateBindGroup(
|
|
Device* device,
|
|
const BindGroupDescriptor* descriptor) {
|
|
uint32_t viewSizeIncrement = 0;
|
|
CPUDescriptorHeapAllocation viewAllocation;
|
|
if (GetCbvUavSrvDescriptorCount() > 0) {
|
|
DAWN_TRY_ASSIGN(viewAllocation, mViewAllocator->AllocateCPUDescriptors());
|
|
viewSizeIncrement = mViewAllocator->GetSizeIncrement();
|
|
}
|
|
|
|
uint32_t samplerSizeIncrement = 0;
|
|
CPUDescriptorHeapAllocation samplerAllocation;
|
|
if (GetSamplerDescriptorCount() > 0) {
|
|
DAWN_TRY_ASSIGN(samplerAllocation, mSamplerAllocator->AllocateCPUDescriptors());
|
|
samplerSizeIncrement = mSamplerAllocator->GetSizeIncrement();
|
|
}
|
|
|
|
return mBindGroupAllocator.Allocate(device, descriptor, viewSizeIncrement, viewAllocation,
|
|
samplerSizeIncrement, samplerAllocation);
|
|
}
|
|
|
|
void BindGroupLayout::DeallocateBindGroup(BindGroup* bindGroup,
|
|
CPUDescriptorHeapAllocation* viewAllocation,
|
|
CPUDescriptorHeapAllocation* samplerAllocation) {
|
|
if (viewAllocation->IsValid()) {
|
|
mViewAllocator->Deallocate(viewAllocation);
|
|
}
|
|
|
|
if (samplerAllocation->IsValid()) {
|
|
mSamplerAllocator->Deallocate(samplerAllocation);
|
|
}
|
|
|
|
mBindGroupAllocator.Deallocate(bindGroup);
|
|
}
|
|
|
|
const std::array<uint32_t, kMaxBindingsPerGroup>& BindGroupLayout::GetBindingOffsets() const {
|
|
return mBindingOffsets;
|
|
}
|
|
|
|
uint32_t BindGroupLayout::GetCbvUavSrvDescriptorTableSize() const {
|
|
return (static_cast<uint32_t>(mDescriptorCounts[CBV] > 0) +
|
|
static_cast<uint32_t>(mDescriptorCounts[UAV] > 0) +
|
|
static_cast<uint32_t>(mDescriptorCounts[SRV] > 0));
|
|
}
|
|
|
|
uint32_t BindGroupLayout::GetSamplerDescriptorTableSize() const {
|
|
return mDescriptorCounts[Sampler] > 0;
|
|
}
|
|
|
|
uint32_t BindGroupLayout::GetCbvUavSrvDescriptorCount() const {
|
|
return mDescriptorCounts[CBV] + mDescriptorCounts[UAV] + mDescriptorCounts[SRV];
|
|
}
|
|
|
|
uint32_t BindGroupLayout::GetSamplerDescriptorCount() const {
|
|
return mDescriptorCounts[Sampler];
|
|
}
|
|
|
|
const D3D12_DESCRIPTOR_RANGE* BindGroupLayout::GetCbvUavSrvDescriptorRanges() const {
|
|
return mRanges;
|
|
}
|
|
|
|
const D3D12_DESCRIPTOR_RANGE* BindGroupLayout::GetSamplerDescriptorRanges() const {
|
|
return &mRanges[Sampler];
|
|
}
|
|
|
|
}} // namespace dawn_native::d3d12
|