mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-03 13:11:34 +00:00
Copy some WGPUHelpers into dawn_native to simplify reentrant code
Bug: none Change-Id: I9d48951019f5e1cfeca3815245a8818d79c3d1da Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/68282 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Loko Kung <lokokung@google.com> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
61a5aeb70b
commit
a50efb961d
@ -331,6 +331,8 @@ source_set("dawn_native_sources") {
|
||||
"VertexFormat.cpp",
|
||||
"VertexFormat.h",
|
||||
"dawn_platform.h",
|
||||
"utils/WGPUHelpers.cpp",
|
||||
"utils/WGPUHelpers.h",
|
||||
]
|
||||
|
||||
if (dawn_use_x11) {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "dawn_native/ObjectType_autogen.h"
|
||||
#include "dawn_native/PassResourceUsageTracker.h"
|
||||
#include "dawn_native/QuerySet.h"
|
||||
#include "dawn_native/utils/WGPUHelpers.h"
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
@ -39,13 +40,10 @@ namespace dawn_native {
|
||||
return store->dispatchIndirectValidationPipeline.Get();
|
||||
}
|
||||
|
||||
ShaderModuleDescriptor descriptor;
|
||||
ShaderModuleWGSLDescriptor wgslDesc;
|
||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||
|
||||
// TODO(https://crbug.com/dawn/1108): Propagate validation feedback from this
|
||||
// shader in various failure modes.
|
||||
wgslDesc.source = R"(
|
||||
Ref<ShaderModuleBase> shaderModule;
|
||||
DAWN_TRY_ASSIGN(shaderModule, utils::CreateShaderModule(device, R"(
|
||||
[[block]] struct UniformParams {
|
||||
maxComputeWorkgroupsPerDimension: u32;
|
||||
clientOffsetInU32: u32;
|
||||
@ -73,34 +71,23 @@ namespace dawn_native {
|
||||
validatedParams.data[i] = numWorkgroups;
|
||||
}
|
||||
}
|
||||
)";
|
||||
)"));
|
||||
|
||||
Ref<ShaderModuleBase> shaderModule;
|
||||
DAWN_TRY_ASSIGN(shaderModule, device->CreateShaderModule(&descriptor));
|
||||
|
||||
std::array<BindGroupLayoutEntry, 3> entries;
|
||||
entries[0].binding = 0;
|
||||
entries[0].visibility = wgpu::ShaderStage::Compute;
|
||||
entries[0].buffer.type = wgpu::BufferBindingType::Uniform;
|
||||
entries[1].binding = 1;
|
||||
entries[1].visibility = wgpu::ShaderStage::Compute;
|
||||
entries[1].buffer.type = kInternalStorageBufferBinding;
|
||||
entries[2].binding = 2;
|
||||
entries[2].visibility = wgpu::ShaderStage::Compute;
|
||||
entries[2].buffer.type = wgpu::BufferBindingType::Storage;
|
||||
|
||||
BindGroupLayoutDescriptor bindGroupLayoutDescriptor;
|
||||
bindGroupLayoutDescriptor.entryCount = entries.size();
|
||||
bindGroupLayoutDescriptor.entries = entries.data();
|
||||
Ref<BindGroupLayoutBase> bindGroupLayout;
|
||||
DAWN_TRY_ASSIGN(bindGroupLayout,
|
||||
device->CreateBindGroupLayout(&bindGroupLayoutDescriptor, true));
|
||||
DAWN_TRY_ASSIGN(
|
||||
bindGroupLayout,
|
||||
utils::MakeBindGroupLayout(
|
||||
device,
|
||||
{
|
||||
{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform},
|
||||
{1, wgpu::ShaderStage::Compute, kInternalStorageBufferBinding},
|
||||
{2, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage},
|
||||
},
|
||||
/* allowInternalBinding */ true));
|
||||
|
||||
PipelineLayoutDescriptor pipelineDescriptor;
|
||||
pipelineDescriptor.bindGroupLayoutCount = 1;
|
||||
pipelineDescriptor.bindGroupLayouts = &bindGroupLayout.Get();
|
||||
Ref<PipelineLayoutBase> pipelineLayout;
|
||||
DAWN_TRY_ASSIGN(pipelineLayout, device->CreatePipelineLayout(&pipelineDescriptor));
|
||||
DAWN_TRY_ASSIGN(pipelineLayout,
|
||||
utils::MakeBasicPipelineLayout(device, bindGroupLayout));
|
||||
|
||||
ComputePipelineDescriptor computePipelineDescriptor = {};
|
||||
computePipelineDescriptor.layout = pipelineLayout.Get();
|
||||
@ -211,21 +198,15 @@ namespace dawn_native {
|
||||
uint32_t storageBufferOffsetAlignment =
|
||||
device->GetLimits().v1.minStorageBufferOffsetAlignment;
|
||||
|
||||
std::array<BindGroupEntry, 3> bindings;
|
||||
|
||||
// Storage binding holding the client's indirect buffer.
|
||||
BindGroupEntry& clientIndirectBinding = bindings[0];
|
||||
clientIndirectBinding.binding = 1;
|
||||
clientIndirectBinding.buffer = indirectBuffer;
|
||||
|
||||
// Let the offset be the indirectOffset, aligned down to |storageBufferOffsetAlignment|.
|
||||
const uint32_t clientOffsetFromAlignedBoundary =
|
||||
indirectOffset % storageBufferOffsetAlignment;
|
||||
const uint64_t clientOffsetAlignedDown = indirectOffset - clientOffsetFromAlignedBoundary;
|
||||
clientIndirectBinding.offset = clientOffsetAlignedDown;
|
||||
const uint64_t clientIndirectBindingOffset = clientOffsetAlignedDown;
|
||||
|
||||
// Let the size of the binding be the additional offset, plus the size.
|
||||
clientIndirectBinding.size = kDispatchIndirectSize + clientOffsetFromAlignedBoundary;
|
||||
const uint64_t clientIndirectBindingSize =
|
||||
kDispatchIndirectSize + clientOffsetFromAlignedBoundary;
|
||||
|
||||
struct UniformParams {
|
||||
uint32_t maxComputeWorkgroupsPerDimension;
|
||||
@ -235,46 +216,30 @@ namespace dawn_native {
|
||||
// Create a uniform buffer to hold parameters for the shader.
|
||||
Ref<BufferBase> uniformBuffer;
|
||||
{
|
||||
BufferDescriptor uniformDesc = {};
|
||||
uniformDesc.size = sizeof(UniformParams);
|
||||
uniformDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
|
||||
uniformDesc.mappedAtCreation = true;
|
||||
DAWN_TRY_ASSIGN(uniformBuffer, device->CreateBuffer(&uniformDesc));
|
||||
|
||||
UniformParams* params = static_cast<UniformParams*>(
|
||||
uniformBuffer->GetMappedRange(0, sizeof(UniformParams)));
|
||||
params->maxComputeWorkgroupsPerDimension =
|
||||
UniformParams params;
|
||||
params.maxComputeWorkgroupsPerDimension =
|
||||
device->GetLimits().v1.maxComputeWorkgroupsPerDimension;
|
||||
params->clientOffsetInU32 = clientOffsetFromAlignedBoundary / sizeof(uint32_t);
|
||||
uniformBuffer->Unmap();
|
||||
}
|
||||
params.clientOffsetInU32 = clientOffsetFromAlignedBoundary / sizeof(uint32_t);
|
||||
|
||||
// Uniform buffer binding pointing to the uniform parameters.
|
||||
BindGroupEntry& uniformBinding = bindings[1];
|
||||
uniformBinding.binding = 0;
|
||||
uniformBinding.buffer = uniformBuffer.Get();
|
||||
uniformBinding.offset = 0;
|
||||
uniformBinding.size = sizeof(UniformParams);
|
||||
DAWN_TRY_ASSIGN(uniformBuffer, utils::CreateBufferFromData(
|
||||
device, wgpu::BufferUsage::Uniform, {params}));
|
||||
}
|
||||
|
||||
// Reserve space in the scratch buffer to hold the validated indirect params.
|
||||
ScratchBuffer& scratchBuffer = store->scratchIndirectStorage;
|
||||
DAWN_TRY(scratchBuffer.EnsureCapacity(kDispatchIndirectSize));
|
||||
Ref<BufferBase> validatedIndirectBuffer = scratchBuffer.GetBuffer();
|
||||
|
||||
// Binding for the validated indirect params.
|
||||
BindGroupEntry& validatedParamsBinding = bindings[2];
|
||||
validatedParamsBinding.binding = 2;
|
||||
validatedParamsBinding.buffer = validatedIndirectBuffer.Get();
|
||||
validatedParamsBinding.offset = 0;
|
||||
validatedParamsBinding.size = kDispatchIndirectSize;
|
||||
|
||||
BindGroupDescriptor bindGroupDescriptor = {};
|
||||
bindGroupDescriptor.layout = layout.Get();
|
||||
bindGroupDescriptor.entryCount = bindings.size();
|
||||
bindGroupDescriptor.entries = bindings.data();
|
||||
|
||||
Ref<BindGroupBase> validationBindGroup;
|
||||
DAWN_TRY_ASSIGN(validationBindGroup, device->CreateBindGroup(&bindGroupDescriptor));
|
||||
DAWN_TRY_ASSIGN(
|
||||
validationBindGroup,
|
||||
utils::MakeBindGroup(
|
||||
device, layout,
|
||||
{
|
||||
{0, uniformBuffer},
|
||||
{1, indirectBuffer, clientIndirectBindingOffset, clientIndirectBindingSize},
|
||||
{2, validatedIndirectBuffer, 0, kDispatchIndirectSize},
|
||||
}));
|
||||
|
||||
// Issue commands to validate the indirect buffer.
|
||||
APISetPipeline(validationPipeline.Get());
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "dawn_native/Sampler.h"
|
||||
#include "dawn_native/Texture.h"
|
||||
#include "dawn_native/ValidationUtils_autogen.h"
|
||||
#include "dawn_native/utils/WGPUHelpers.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
@ -191,13 +192,9 @@ namespace dawn_native {
|
||||
if (GetCachedPipeline(store, dstFormat) == nullptr) {
|
||||
// Create vertex shader module if not cached before.
|
||||
if (store->copyTextureForBrowser == nullptr) {
|
||||
ShaderModuleDescriptor descriptor;
|
||||
ShaderModuleWGSLDescriptor wgslDesc;
|
||||
wgslDesc.source = sCopyTextureForBrowserShader;
|
||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||
|
||||
DAWN_TRY_ASSIGN(store->copyTextureForBrowser,
|
||||
device->CreateShaderModule(&descriptor));
|
||||
DAWN_TRY_ASSIGN(
|
||||
store->copyTextureForBrowser,
|
||||
utils::CreateShaderModule(device, sCopyTextureForBrowserShader));
|
||||
}
|
||||
|
||||
ShaderModuleBase* shaderModule = store->copyTextureForBrowser.Get();
|
||||
@ -307,13 +304,6 @@ namespace dawn_native {
|
||||
Ref<BindGroupLayoutBase> layout;
|
||||
DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));
|
||||
|
||||
// Prepare bind group descriptor
|
||||
BindGroupEntry bindGroupEntries[3] = {};
|
||||
BindGroupDescriptor bgDesc = {};
|
||||
bgDesc.layout = layout.Get();
|
||||
bgDesc.entryCount = 3;
|
||||
bgDesc.entries = bindGroupEntries;
|
||||
|
||||
Extent3D srcTextureSize = source->texture->GetSize();
|
||||
|
||||
// Prepare binding 0 resource: uniform buffer.
|
||||
@ -336,14 +326,11 @@ namespace dawn_native {
|
||||
// Set alpha op.
|
||||
uniformData.alphaOp = options->alphaOp;
|
||||
|
||||
BufferDescriptor uniformDesc = {};
|
||||
uniformDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
|
||||
uniformDesc.size = sizeof(uniformData);
|
||||
Ref<BufferBase> uniformBuffer;
|
||||
DAWN_TRY_ASSIGN(uniformBuffer, device->CreateBuffer(&uniformDesc));
|
||||
|
||||
DAWN_TRY(device->GetQueue()->WriteBuffer(uniformBuffer.Get(), 0, &uniformData,
|
||||
sizeof(uniformData)));
|
||||
DAWN_TRY_ASSIGN(
|
||||
uniformBuffer,
|
||||
utils::CreateBufferFromData(
|
||||
device, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform, {uniformData}));
|
||||
|
||||
// Prepare binding 1 resource: sampler
|
||||
// Use default configuration, filterMode set to Nearest for min and mag.
|
||||
@ -360,18 +347,11 @@ namespace dawn_native {
|
||||
DAWN_TRY_ASSIGN(srcTextureView,
|
||||
device->CreateTextureView(source->texture, &srcTextureViewDesc));
|
||||
|
||||
// Set bind group entries.
|
||||
bindGroupEntries[0].binding = 0;
|
||||
bindGroupEntries[0].buffer = uniformBuffer.Get();
|
||||
bindGroupEntries[0].size = sizeof(uniformData);
|
||||
bindGroupEntries[1].binding = 1;
|
||||
bindGroupEntries[1].sampler = sampler.Get();
|
||||
bindGroupEntries[2].binding = 2;
|
||||
bindGroupEntries[2].textureView = srcTextureView.Get();
|
||||
|
||||
// Create bind group after all binding entries are set.
|
||||
Ref<BindGroupBase> bindGroup;
|
||||
DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bgDesc));
|
||||
DAWN_TRY_ASSIGN(bindGroup, utils::MakeBindGroup(
|
||||
device, layout,
|
||||
{{0, uniformBuffer}, {1, sampler}, {2, srcTextureView}}));
|
||||
|
||||
// Create command encoder.
|
||||
CommandEncoderDescriptor encoderDesc = {};
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/InternalPipelineStore.h"
|
||||
#include "dawn_native/Queue.h"
|
||||
#include "dawn_native/utils/WGPUHelpers.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
@ -138,37 +139,27 @@ namespace dawn_native {
|
||||
if (store->renderValidationPipeline == nullptr) {
|
||||
// Create compute shader module if not cached before.
|
||||
if (store->renderValidationShader == nullptr) {
|
||||
ShaderModuleDescriptor descriptor;
|
||||
ShaderModuleWGSLDescriptor wgslDesc;
|
||||
wgslDesc.source = sRenderValidationShaderSource;
|
||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||
DAWN_TRY_ASSIGN(store->renderValidationShader,
|
||||
device->CreateShaderModule(&descriptor));
|
||||
DAWN_TRY_ASSIGN(
|
||||
store->renderValidationShader,
|
||||
utils::CreateShaderModule(device, sRenderValidationShaderSource));
|
||||
}
|
||||
|
||||
BindGroupLayoutEntry entries[3];
|
||||
entries[0].binding = 0;
|
||||
entries[0].visibility = wgpu::ShaderStage::Compute;
|
||||
entries[0].buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
|
||||
entries[1].binding = 1;
|
||||
entries[1].visibility = wgpu::ShaderStage::Compute;
|
||||
entries[1].buffer.type = kInternalStorageBufferBinding;
|
||||
entries[2].binding = 2;
|
||||
entries[2].visibility = wgpu::ShaderStage::Compute;
|
||||
entries[2].buffer.type = wgpu::BufferBindingType::Storage;
|
||||
|
||||
BindGroupLayoutDescriptor bindGroupLayoutDescriptor;
|
||||
bindGroupLayoutDescriptor.entryCount = 3;
|
||||
bindGroupLayoutDescriptor.entries = entries;
|
||||
Ref<BindGroupLayoutBase> bindGroupLayout;
|
||||
DAWN_TRY_ASSIGN(bindGroupLayout,
|
||||
device->CreateBindGroupLayout(&bindGroupLayoutDescriptor, true));
|
||||
DAWN_TRY_ASSIGN(
|
||||
bindGroupLayout,
|
||||
utils::MakeBindGroupLayout(
|
||||
device,
|
||||
{
|
||||
{0, wgpu::ShaderStage::Compute,
|
||||
wgpu::BufferBindingType::ReadOnlyStorage},
|
||||
{1, wgpu::ShaderStage::Compute, kInternalStorageBufferBinding},
|
||||
{2, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage},
|
||||
},
|
||||
/* allowInternalBinding */ true));
|
||||
|
||||
PipelineLayoutDescriptor pipelineDescriptor;
|
||||
pipelineDescriptor.bindGroupLayoutCount = 1;
|
||||
pipelineDescriptor.bindGroupLayouts = &bindGroupLayout.Get();
|
||||
Ref<PipelineLayoutBase> pipelineLayout;
|
||||
DAWN_TRY_ASSIGN(pipelineLayout, device->CreatePipelineLayout(&pipelineDescriptor));
|
||||
DAWN_TRY_ASSIGN(pipelineLayout,
|
||||
utils::MakeBasicPipelineLayout(device, bindGroupLayout));
|
||||
|
||||
ComputePipelineDescriptor computePipelineDescriptor = {};
|
||||
computePipelineDescriptor.layout = pipelineLayout.Get();
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "dawn_native/ComputePipeline.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/InternalPipelineStore.h"
|
||||
#include "dawn_native/utils/WGPUHelpers.h"
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
@ -113,36 +114,27 @@ namespace dawn_native {
|
||||
if (store->timestampComputePipeline == nullptr) {
|
||||
// Create compute shader module if not cached before.
|
||||
if (store->timestampCS == nullptr) {
|
||||
ShaderModuleDescriptor descriptor;
|
||||
ShaderModuleWGSLDescriptor wgslDesc;
|
||||
wgslDesc.source = sConvertTimestampsToNanoseconds;
|
||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||
|
||||
DAWN_TRY_ASSIGN(store->timestampCS, device->CreateShaderModule(&descriptor));
|
||||
DAWN_TRY_ASSIGN(
|
||||
store->timestampCS,
|
||||
utils::CreateShaderModule(device, sConvertTimestampsToNanoseconds));
|
||||
}
|
||||
|
||||
// Create binding group layout
|
||||
std::array<BindGroupLayoutEntry, 3> entries = {};
|
||||
for (uint32_t i = 0; i < entries.size(); i++) {
|
||||
entries[i].binding = i;
|
||||
entries[i].visibility = wgpu::ShaderStage::Compute;
|
||||
}
|
||||
entries[0].buffer.type = kInternalStorageBufferBinding;
|
||||
entries[1].buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
|
||||
entries[2].buffer.type = wgpu::BufferBindingType::Uniform;
|
||||
|
||||
BindGroupLayoutDescriptor bglDesc;
|
||||
bglDesc.entryCount = static_cast<uint32_t>(entries.size());
|
||||
bglDesc.entries = entries.data();
|
||||
Ref<BindGroupLayoutBase> bgl;
|
||||
DAWN_TRY_ASSIGN(bgl, device->CreateBindGroupLayout(&bglDesc, true));
|
||||
DAWN_TRY_ASSIGN(
|
||||
bgl, utils::MakeBindGroupLayout(
|
||||
device,
|
||||
{
|
||||
{0, wgpu::ShaderStage::Compute, kInternalStorageBufferBinding},
|
||||
{1, wgpu::ShaderStage::Compute,
|
||||
wgpu::BufferBindingType::ReadOnlyStorage},
|
||||
{2, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform},
|
||||
},
|
||||
/* allowInternalBinding */ true));
|
||||
|
||||
// Create pipeline layout
|
||||
PipelineLayoutDescriptor plDesc;
|
||||
plDesc.bindGroupLayoutCount = 1;
|
||||
plDesc.bindGroupLayouts = &bgl.Get();
|
||||
Ref<PipelineLayoutBase> layout;
|
||||
DAWN_TRY_ASSIGN(layout, device->CreatePipelineLayout(&plDesc));
|
||||
DAWN_TRY_ASSIGN(layout, utils::MakeBasicPipelineLayout(device, bgl));
|
||||
|
||||
// Create ComputePipeline.
|
||||
ComputePipelineDescriptor computePipelineDesc = {};
|
||||
@ -173,27 +165,11 @@ namespace dawn_native {
|
||||
Ref<BindGroupLayoutBase> layout;
|
||||
DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));
|
||||
|
||||
// Prepare bind group descriptor
|
||||
std::array<BindGroupEntry, 3> bindGroupEntries = {};
|
||||
BindGroupDescriptor bgDesc = {};
|
||||
bgDesc.layout = layout.Get();
|
||||
bgDesc.entryCount = 3;
|
||||
bgDesc.entries = bindGroupEntries.data();
|
||||
|
||||
// Set bind group entries.
|
||||
bindGroupEntries[0].binding = 0;
|
||||
bindGroupEntries[0].buffer = timestamps;
|
||||
bindGroupEntries[0].size = timestamps->GetSize();
|
||||
bindGroupEntries[1].binding = 1;
|
||||
bindGroupEntries[1].buffer = availability;
|
||||
bindGroupEntries[1].size = availability->GetSize();
|
||||
bindGroupEntries[2].binding = 2;
|
||||
bindGroupEntries[2].buffer = params;
|
||||
bindGroupEntries[2].size = params->GetSize();
|
||||
|
||||
// Create bind group after all binding entries are set.
|
||||
Ref<BindGroupBase> bindGroup;
|
||||
DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bgDesc));
|
||||
DAWN_TRY_ASSIGN(bindGroup,
|
||||
utils::MakeBindGroup(device, layout,
|
||||
{{0, timestamps}, {1, availability}, {2, params}}));
|
||||
|
||||
// Create compute encoder and issue dispatch.
|
||||
ComputePassDescriptor passDesc = {};
|
||||
|
188
src/dawn_native/utils/WGPUHelpers.cpp
Normal file
188
src/dawn_native/utils/WGPUHelpers.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
// 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/utils/WGPUHelpers.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "dawn_native/BindGroup.h"
|
||||
#include "dawn_native/BindGroupLayout.h"
|
||||
#include "dawn_native/Buffer.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/PipelineLayout.h"
|
||||
#include "dawn_native/Queue.h"
|
||||
#include "dawn_native/Sampler.h"
|
||||
#include "dawn_native/ShaderModule.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
namespace dawn_native { namespace utils {
|
||||
|
||||
ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(DeviceBase* device,
|
||||
const char* source) {
|
||||
ShaderModuleWGSLDescriptor wgslDesc;
|
||||
wgslDesc.source = source;
|
||||
ShaderModuleDescriptor descriptor;
|
||||
descriptor.nextInChain = &wgslDesc;
|
||||
return device->CreateShaderModule(&descriptor);
|
||||
}
|
||||
|
||||
ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device,
|
||||
wgpu::BufferUsage usage,
|
||||
const void* data,
|
||||
uint64_t size) {
|
||||
BufferDescriptor descriptor;
|
||||
descriptor.size = size;
|
||||
descriptor.usage = usage;
|
||||
descriptor.mappedAtCreation = true;
|
||||
Ref<BufferBase> buffer;
|
||||
DAWN_TRY_ASSIGN(buffer, device->CreateBuffer(&descriptor));
|
||||
memcpy(buffer->GetMappedRange(0, size), data, size);
|
||||
buffer->Unmap();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ResultOrError<Ref<PipelineLayoutBase>> MakeBasicPipelineLayout(
|
||||
DeviceBase* device,
|
||||
const Ref<BindGroupLayoutBase>& bindGroupLayout) {
|
||||
PipelineLayoutDescriptor descriptor;
|
||||
descriptor.bindGroupLayoutCount = 1;
|
||||
BindGroupLayoutBase* bgl = bindGroupLayout.Get();
|
||||
descriptor.bindGroupLayouts = &bgl;
|
||||
return device->CreatePipelineLayout(&descriptor);
|
||||
}
|
||||
|
||||
ResultOrError<Ref<BindGroupLayoutBase>> MakeBindGroupLayout(
|
||||
DeviceBase* device,
|
||||
std::initializer_list<BindingLayoutEntryInitializationHelper> entriesInitializer,
|
||||
bool allowInternalBinding) {
|
||||
std::vector<BindGroupLayoutEntry> entries;
|
||||
for (const BindingLayoutEntryInitializationHelper& entry : entriesInitializer) {
|
||||
entries.push_back(entry);
|
||||
}
|
||||
|
||||
BindGroupLayoutDescriptor descriptor;
|
||||
descriptor.entryCount = static_cast<uint32_t>(entries.size());
|
||||
descriptor.entries = entries.data();
|
||||
return device->CreateBindGroupLayout(&descriptor, allowInternalBinding);
|
||||
}
|
||||
|
||||
BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper(
|
||||
uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::BufferBindingType bufferType,
|
||||
bool bufferHasDynamicOffset,
|
||||
uint64_t bufferMinBindingSize) {
|
||||
binding = entryBinding;
|
||||
visibility = entryVisibility;
|
||||
buffer.type = bufferType;
|
||||
buffer.hasDynamicOffset = bufferHasDynamicOffset;
|
||||
buffer.minBindingSize = bufferMinBindingSize;
|
||||
}
|
||||
|
||||
BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper(
|
||||
uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::SamplerBindingType samplerType) {
|
||||
binding = entryBinding;
|
||||
visibility = entryVisibility;
|
||||
sampler.type = samplerType;
|
||||
}
|
||||
|
||||
BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper(
|
||||
uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::TextureSampleType textureSampleType,
|
||||
wgpu::TextureViewDimension textureViewDimension,
|
||||
bool textureMultisampled) {
|
||||
binding = entryBinding;
|
||||
visibility = entryVisibility;
|
||||
texture.sampleType = textureSampleType;
|
||||
texture.viewDimension = textureViewDimension;
|
||||
texture.multisampled = textureMultisampled;
|
||||
}
|
||||
|
||||
BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper(
|
||||
uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::StorageTextureAccess storageTextureAccess,
|
||||
wgpu::TextureFormat format,
|
||||
wgpu::TextureViewDimension textureViewDimension) {
|
||||
binding = entryBinding;
|
||||
visibility = entryVisibility;
|
||||
storageTexture.access = storageTextureAccess;
|
||||
storageTexture.format = format;
|
||||
storageTexture.viewDimension = textureViewDimension;
|
||||
}
|
||||
|
||||
BindingLayoutEntryInitializationHelper::BindingLayoutEntryInitializationHelper(
|
||||
const BindGroupLayoutEntry& entry)
|
||||
: BindGroupLayoutEntry(entry) {
|
||||
}
|
||||
|
||||
BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
|
||||
const Ref<SamplerBase>& sampler)
|
||||
: binding(binding), sampler(sampler) {
|
||||
}
|
||||
|
||||
BindingInitializationHelper::BindingInitializationHelper(
|
||||
uint32_t binding,
|
||||
const Ref<TextureViewBase>& textureView)
|
||||
: binding(binding), textureView(textureView) {
|
||||
}
|
||||
|
||||
BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
|
||||
const Ref<BufferBase>& buffer,
|
||||
uint64_t offset,
|
||||
uint64_t size)
|
||||
: binding(binding), buffer(buffer), offset(offset), size(size) {
|
||||
}
|
||||
|
||||
BindingInitializationHelper::~BindingInitializationHelper() = default;
|
||||
|
||||
BindGroupEntry BindingInitializationHelper::GetAsBinding() const {
|
||||
BindGroupEntry result;
|
||||
|
||||
result.binding = binding;
|
||||
result.sampler = sampler.Get();
|
||||
result.textureView = textureView.Get();
|
||||
result.buffer = buffer.Get();
|
||||
result.offset = offset;
|
||||
result.size = size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ResultOrError<Ref<BindGroupBase>> MakeBindGroup(
|
||||
DeviceBase* device,
|
||||
const Ref<BindGroupLayoutBase>& layout,
|
||||
std::initializer_list<BindingInitializationHelper> entriesInitializer) {
|
||||
std::vector<BindGroupEntry> entries;
|
||||
for (const BindingInitializationHelper& helper : entriesInitializer) {
|
||||
entries.push_back(helper.GetAsBinding());
|
||||
}
|
||||
|
||||
BindGroupDescriptor descriptor;
|
||||
descriptor.layout = layout.Get();
|
||||
descriptor.entryCount = entries.size();
|
||||
descriptor.entries = entries.data();
|
||||
|
||||
return device->CreateBindGroup(&descriptor);
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::utils
|
120
src/dawn_native/utils/WGPUHelpers.h
Normal file
120
src/dawn_native/utils/WGPUHelpers.h
Normal file
@ -0,0 +1,120 @@
|
||||
// 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.
|
||||
|
||||
#ifndef DAWNNATIVE_UTILS_WGPUHELPERS_H_
|
||||
#define DAWNNATIVE_UTILS_WGPUHELPERS_H_
|
||||
|
||||
#include <dawn_native/dawn_platform.h>
|
||||
|
||||
#include <array>
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
#include "common/RefCounted.h"
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
namespace dawn_native { namespace utils {
|
||||
|
||||
ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(DeviceBase* device, const char* source);
|
||||
|
||||
ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device,
|
||||
wgpu::BufferUsage usage,
|
||||
const void* data,
|
||||
uint64_t size);
|
||||
|
||||
template <typename T>
|
||||
ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device,
|
||||
wgpu::BufferUsage usage,
|
||||
std::initializer_list<T> data) {
|
||||
return CreateBufferFromData(device, usage, data.begin(), uint32_t(sizeof(T) * data.size()));
|
||||
}
|
||||
|
||||
ResultOrError<Ref<PipelineLayoutBase>> MakeBasicPipelineLayout(
|
||||
DeviceBase* device,
|
||||
const Ref<BindGroupLayoutBase>& bindGroupLayout);
|
||||
|
||||
// Helpers to make creating bind group layouts look nicer:
|
||||
//
|
||||
// utils::MakeBindGroupLayout(device, {
|
||||
// {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
|
||||
// {1, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
|
||||
// {3, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}
|
||||
// });
|
||||
|
||||
struct BindingLayoutEntryInitializationHelper : BindGroupLayoutEntry {
|
||||
BindingLayoutEntryInitializationHelper(uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::BufferBindingType bufferType,
|
||||
bool bufferHasDynamicOffset = false,
|
||||
uint64_t bufferMinBindingSize = 0);
|
||||
BindingLayoutEntryInitializationHelper(uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::SamplerBindingType samplerType);
|
||||
BindingLayoutEntryInitializationHelper(
|
||||
uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::TextureSampleType textureSampleType,
|
||||
wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
bool textureMultisampled = false);
|
||||
BindingLayoutEntryInitializationHelper(
|
||||
uint32_t entryBinding,
|
||||
wgpu::ShaderStage entryVisibility,
|
||||
wgpu::StorageTextureAccess storageTextureAccess,
|
||||
wgpu::TextureFormat format,
|
||||
wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D);
|
||||
|
||||
BindingLayoutEntryInitializationHelper(const BindGroupLayoutEntry& entry);
|
||||
};
|
||||
|
||||
ResultOrError<Ref<BindGroupLayoutBase>> MakeBindGroupLayout(
|
||||
DeviceBase* device,
|
||||
std::initializer_list<BindingLayoutEntryInitializationHelper> entriesInitializer,
|
||||
bool allowInternalBinding = false);
|
||||
|
||||
// Helpers to make creating bind groups look nicer:
|
||||
//
|
||||
// utils::MakeBindGroup(device, layout, {
|
||||
// {0, mySampler},
|
||||
// {1, myBuffer, offset, size},
|
||||
// {3, myTextureView}
|
||||
// });
|
||||
|
||||
// Structure with one constructor per-type of bindings, so that the initializer_list accepts
|
||||
// bindings with the right type and no extra information.
|
||||
struct BindingInitializationHelper {
|
||||
BindingInitializationHelper(uint32_t binding, const Ref<SamplerBase>& sampler);
|
||||
BindingInitializationHelper(uint32_t binding, const Ref<TextureViewBase>& textureView);
|
||||
BindingInitializationHelper(uint32_t binding,
|
||||
const Ref<BufferBase>& buffer,
|
||||
uint64_t offset = 0,
|
||||
uint64_t size = wgpu::kWholeSize);
|
||||
~BindingInitializationHelper();
|
||||
|
||||
BindGroupEntry GetAsBinding() const;
|
||||
|
||||
uint32_t binding;
|
||||
Ref<SamplerBase> sampler;
|
||||
Ref<TextureViewBase> textureView;
|
||||
Ref<BufferBase> buffer;
|
||||
uint64_t offset = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
ResultOrError<Ref<BindGroupBase>> MakeBindGroup(
|
||||
DeviceBase* device,
|
||||
const Ref<BindGroupLayoutBase>& layout,
|
||||
std::initializer_list<BindingInitializationHelper> entriesInitializer);
|
||||
}} // namespace dawn_native::utils
|
||||
|
||||
#endif // DAWNNATIVE_UTILS_WGPUHELPERS_H_
|
Loading…
x
Reference in New Issue
Block a user