dawn_native: Use refcount-safe methods for reentrant object creation

Previously all uses of reentrant object creation in Dawn native
needed to manually AcquireRef. Change them to use CreateFooInternal that
returns a ResultOrError<Ref<>> and are renamed to CreateFoo.

Bug: dawn:723

Change-Id: Ifcda3659d02cc5a4c63c248dc53af7fee7c4a61d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/46626
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Corentin Wallez 2021-04-19 08:52:35 +00:00 committed by Commit Bot service account
parent b6c0dac110
commit 0af4a834a9
12 changed files with 174 additions and 154 deletions

View File

@ -451,9 +451,9 @@ namespace dawn_native {
BufferDescriptor availabilityDesc = {};
availabilityDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst;
availabilityDesc.size = querySet->GetQueryCount() * sizeof(uint32_t);
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BufferBase> availabilityBuffer =
AcquireRef(device->APICreateBuffer(&availabilityDesc));
Ref<BufferBase> availabilityBuffer;
DAWN_TRY_ASSIGN(availabilityBuffer, device->CreateBuffer(&availabilityDesc));
DAWN_TRY(device->GetQueue()->WriteBuffer(availabilityBuffer.Get(), 0,
availability.data(),
availability.size() * sizeof(uint32_t)));
@ -461,17 +461,18 @@ namespace dawn_native {
// Timestamp params uniform buffer
TimestampParams params = {queryCount, static_cast<uint32_t>(destinationOffset),
device->GetTimestampPeriodInNS()};
BufferDescriptor parmsDesc = {};
parmsDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
parmsDesc.size = sizeof(params);
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BufferBase> paramsBuffer = AcquireRef(device->APICreateBuffer(&parmsDesc));
Ref<BufferBase> paramsBuffer;
DAWN_TRY_ASSIGN(paramsBuffer, device->CreateBuffer(&parmsDesc));
DAWN_TRY(
device->GetQueue()->WriteBuffer(paramsBuffer.Get(), 0, &params, sizeof(params)));
EncodeConvertTimestampsToNanoseconds(encoder, destination, availabilityBuffer.Get(),
paramsBuffer.Get());
return {};
return EncodeConvertTimestampsToNanoseconds(
encoder, destination, availabilityBuffer.Get(), paramsBuffer.Get());
}
} // namespace

View File

@ -139,7 +139,7 @@ namespace dawn_native {
return nullptr;
}
RenderPipelineBase* GetOrCreateCopyTextureForBrowserPipeline(
ResultOrError<RenderPipelineBase*> GetOrCreateCopyTextureForBrowserPipeline(
DeviceBase* device,
wgpu::TextureFormat dstFormat) {
InternalPipelineStore* store = device->GetInternalPipelineStore();
@ -152,9 +152,8 @@ namespace dawn_native {
wgslDesc.source = sCopyTextureForBrowserVertex;
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
store->copyTextureForBrowserVS =
AcquireRef(device->APICreateShaderModule(&descriptor));
DAWN_TRY_ASSIGN(store->copyTextureForBrowserVS,
device->CreateShaderModule(&descriptor));
}
ShaderModuleBase* vertexModule = store->copyTextureForBrowserVS.Get();
@ -165,9 +164,8 @@ namespace dawn_native {
ShaderModuleWGSLDescriptor wgslDesc;
wgslDesc.source = sCopyTextureForBrowserFragment;
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
store->copyTextureForBrowserFS =
AcquireRef(device->APICreateShaderModule(&descriptor));
DAWN_TRY_ASSIGN(store->copyTextureForBrowserFS,
device->CreateShaderModule(&descriptor));
}
ShaderModuleBase* fragmentModule = store->copyTextureForBrowserFS.Get();
@ -200,9 +198,9 @@ namespace dawn_native {
fragment.targetCount = 1;
fragment.targets = &target;
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
store->copyTextureForBrowserPipelines.insert(
{dstFormat, AcquireRef(device->APICreateRenderPipeline2(&renderPipelineDesc))});
Ref<RenderPipelineBase> pipeline;
DAWN_TRY_ASSIGN(pipeline, device->CreateRenderPipeline(&renderPipelineDesc));
store->copyTextureForBrowserPipelines.insert({dstFormat, std::move(pipeline)});
}
return GetCachedPipeline(store, dstFormat);
@ -245,12 +243,13 @@ namespace dawn_native {
// TODO(shaobo.yan@intel.com): In D3D12 and Vulkan, compatible texture format can directly
// copy to each other. This can be a potential fast path.
RenderPipelineBase* pipeline = GetOrCreateCopyTextureForBrowserPipeline(
device, destination->texture->GetFormat().format);
RenderPipelineBase* pipeline;
DAWN_TRY_ASSIGN(pipeline, GetOrCreateCopyTextureForBrowserPipeline(
device, destination->texture->GetFormat().format));
// Prepare bind group layout.
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BindGroupLayoutBase> layout = AcquireRef(pipeline->APIGetBindGroupLayout(0));
Ref<BindGroupLayoutBase> layout;
DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));
// Prepare bind group descriptor
BindGroupEntry bindGroupEntries[3] = {};
@ -280,8 +279,8 @@ namespace dawn_native {
BufferDescriptor uniformDesc = {};
uniformDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
uniformDesc.size = sizeof(uniformData);
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BufferBase> uniformBuffer = AcquireRef(device->APICreateBuffer(&uniformDesc));
Ref<BufferBase> uniformBuffer;
DAWN_TRY_ASSIGN(uniformBuffer, device->CreateBuffer(&uniformDesc));
DAWN_TRY(device->GetQueue()->WriteBuffer(uniformBuffer.Get(), 0, uniformData,
sizeof(uniformData)));
@ -289,16 +288,16 @@ namespace dawn_native {
// Prepare binding 1 resource: sampler
// Use default configuration, filterMode set to Nearest for min and mag.
SamplerDescriptor samplerDesc = {};
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<SamplerBase> sampler = AcquireRef(device->APICreateSampler(&samplerDesc));
Ref<SamplerBase> sampler;
DAWN_TRY_ASSIGN(sampler, device->CreateSampler(&samplerDesc));
// Prepare binding 2 resource: sampled texture
TextureViewDescriptor srcTextureViewDesc = {};
srcTextureViewDesc.baseMipLevel = source->mipLevel;
srcTextureViewDesc.mipLevelCount = 1;
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<TextureViewBase> srcTextureView =
AcquireRef(source->texture->APICreateView(&srcTextureViewDesc));
Ref<TextureViewBase> srcTextureView;
DAWN_TRY_ASSIGN(srcTextureView,
device->CreateTextureView(source->texture, &srcTextureViewDesc));
// Set bind group entries.
bindGroupEntries[0].binding = 0;
@ -310,8 +309,8 @@ namespace dawn_native {
bindGroupEntries[2].textureView = srcTextureView.Get();
// Create bind group after all binding entries are set.
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BindGroupBase> bindGroup = AcquireRef(device->APICreateBindGroup(&bgDesc));
Ref<BindGroupBase> bindGroup;
DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bgDesc));
// Create command encoder.
CommandEncoderDescriptor encoderDesc = {};
@ -322,9 +321,9 @@ namespace dawn_native {
TextureViewDescriptor dstTextureViewDesc;
dstTextureViewDesc.baseMipLevel = destination->mipLevel;
dstTextureViewDesc.mipLevelCount = 1;
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<TextureViewBase> dstView =
AcquireRef(destination->texture->APICreateView(&dstTextureViewDesc));
Ref<TextureViewBase> dstView;
DAWN_TRY_ASSIGN(dstView,
device->CreateTextureView(destination->texture, &dstTextureViewDesc));
// Prepare render pass color attachment descriptor.
RenderPassColorAttachmentDescriptor colorAttachmentDesc;

View File

@ -683,7 +683,7 @@ namespace dawn_native {
BindGroupBase* DeviceBase::APICreateBindGroup(const BindGroupDescriptor* descriptor) {
Ref<BindGroupBase> result;
if (ConsumedError(CreateBindGroupInternal(descriptor), &result)) {
if (ConsumedError(CreateBindGroup(descriptor), &result)) {
return BindGroupBase::MakeError(this);
}
return result.Detach();
@ -691,14 +691,14 @@ namespace dawn_native {
BindGroupLayoutBase* DeviceBase::APICreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor) {
Ref<BindGroupLayoutBase> result;
if (ConsumedError(CreateBindGroupLayoutInternal(descriptor), &result)) {
if (ConsumedError(CreateBindGroupLayout(descriptor), &result)) {
return BindGroupLayoutBase::MakeError(this);
}
return result.Detach();
}
BufferBase* DeviceBase::APICreateBuffer(const BufferDescriptor* descriptor) {
Ref<BufferBase> result = nullptr;
if (ConsumedError(CreateBufferInternal(descriptor), &result)) {
if (ConsumedError(CreateBuffer(descriptor), &result)) {
ASSERT(result == nullptr);
return BufferBase::MakeError(this, descriptor);
}
@ -711,7 +711,7 @@ namespace dawn_native {
ComputePipelineBase* DeviceBase::APICreateComputePipeline(
const ComputePipelineDescriptor* descriptor) {
Ref<ComputePipelineBase> result;
if (ConsumedError(CreateComputePipelineInternal(descriptor), &result)) {
if (ConsumedError(CreateComputePipeline(descriptor), &result)) {
return ComputePipelineBase::MakeError(this);
}
return result.Detach();
@ -719,10 +719,10 @@ namespace dawn_native {
void DeviceBase::APICreateComputePipelineAsync(const ComputePipelineDescriptor* descriptor,
WGPUCreateComputePipelineAsyncCallback callback,
void* userdata) {
MaybeError maybeResult = CreateComputePipelineAsyncInternal(descriptor, callback, userdata);
MaybeError maybeResult = CreateComputePipelineAsync(descriptor, callback, userdata);
// Call the callback directly when a validation error has been found in the front-end
// validations. If there is no error, then CreateComputePipelineAsyncInternal will call the
// validations. If there is no error, then CreateComputePipelineAsync will call the
// callback.
if (maybeResult.IsError()) {
std::unique_ptr<ErrorData> error = maybeResult.AcquireError();
@ -733,21 +733,21 @@ namespace dawn_native {
PipelineLayoutBase* DeviceBase::APICreatePipelineLayout(
const PipelineLayoutDescriptor* descriptor) {
Ref<PipelineLayoutBase> result;
if (ConsumedError(CreatePipelineLayoutInternal(descriptor), &result)) {
if (ConsumedError(CreatePipelineLayout(descriptor), &result)) {
return PipelineLayoutBase::MakeError(this);
}
return result.Detach();
}
QuerySetBase* DeviceBase::APICreateQuerySet(const QuerySetDescriptor* descriptor) {
Ref<QuerySetBase> result;
if (ConsumedError(CreateQuerySetInternal(descriptor), &result)) {
if (ConsumedError(CreateQuerySet(descriptor), &result)) {
return QuerySetBase::MakeError(this);
}
return result.Detach();
}
SamplerBase* DeviceBase::APICreateSampler(const SamplerDescriptor* descriptor) {
Ref<SamplerBase> result;
if (ConsumedError(CreateSamplerInternal(descriptor), &result)) {
if (ConsumedError(CreateSampler(descriptor), &result)) {
return SamplerBase::MakeError(this);
}
return result.Detach();
@ -756,7 +756,7 @@ namespace dawn_native {
WGPUCreateRenderPipelineAsyncCallback callback,
void* userdata) {
ResultOrError<Ref<RenderPipelineBase>> maybeResult =
CreateRenderPipelineInternal(descriptor);
CreateRenderPipeline(descriptor);
if (maybeResult.IsError()) {
std::unique_ptr<ErrorData> error = maybeResult.AcquireError();
callback(WGPUCreatePipelineAsyncStatus_Error, nullptr, error->GetMessage().c_str(),
@ -773,7 +773,7 @@ namespace dawn_native {
RenderBundleEncoder* DeviceBase::APICreateRenderBundleEncoder(
const RenderBundleEncoderDescriptor* descriptor) {
Ref<RenderBundleEncoder> result;
if (ConsumedError(CreateRenderBundleEncoderInternal(descriptor), &result)) {
if (ConsumedError(CreateRenderBundleEncoder(descriptor), &result)) {
return RenderBundleEncoder::MakeError(this);
}
return result.Detach();
@ -873,7 +873,7 @@ namespace dawn_native {
}
Ref<RenderPipelineBase> result;
if (ConsumedError(CreateRenderPipelineInternal(&normalizedDescriptor), &result)) {
if (ConsumedError(CreateRenderPipeline(&normalizedDescriptor), &result)) {
return RenderPipelineBase::MakeError(this);
}
return result.Detach();
@ -881,7 +881,7 @@ namespace dawn_native {
RenderPipelineBase* DeviceBase::APICreateRenderPipeline2(
const RenderPipelineDescriptor2* descriptor) {
Ref<RenderPipelineBase> result;
if (ConsumedError(CreateRenderPipelineInternal(descriptor), &result)) {
if (ConsumedError(CreateRenderPipeline(descriptor), &result)) {
return RenderPipelineBase::MakeError(this);
}
return result.Detach();
@ -889,7 +889,7 @@ namespace dawn_native {
ShaderModuleBase* DeviceBase::APICreateShaderModule(const ShaderModuleDescriptor* descriptor) {
Ref<ShaderModuleBase> result;
ShaderModuleParseResult parseResult = {};
if (ConsumedError(CreateShaderModuleInternal(descriptor, &parseResult), &result)) {
if (ConsumedError(CreateShaderModule(descriptor, &parseResult), &result)) {
return ShaderModuleBase::MakeError(this, std::move(parseResult.compilationMessages));
}
return result.Detach();
@ -897,26 +897,18 @@ namespace dawn_native {
SwapChainBase* DeviceBase::APICreateSwapChain(Surface* surface,
const SwapChainDescriptor* descriptor) {
Ref<SwapChainBase> result;
if (ConsumedError(CreateSwapChainInternal(surface, descriptor), &result)) {
if (ConsumedError(CreateSwapChain(surface, descriptor), &result)) {
return SwapChainBase::MakeError(this);
}
return result.Detach();
}
TextureBase* DeviceBase::APICreateTexture(const TextureDescriptor* descriptor) {
Ref<TextureBase> result;
if (ConsumedError(CreateTextureInternal(descriptor), &result)) {
if (ConsumedError(CreateTexture(descriptor), &result)) {
return TextureBase::MakeError(this);
}
return result.Detach();
}
TextureViewBase* DeviceBase::CreateTextureView(TextureBase* texture,
const TextureViewDescriptor* descriptor) {
Ref<TextureViewBase> result;
if (ConsumedError(CreateTextureViewInternal(texture, descriptor), &result)) {
return TextureViewBase::MakeError(this);
}
return result.Detach();
}
// For Dawn Wire
@ -983,7 +975,7 @@ namespace dawn_native {
ExternalTextureBase* DeviceBase::APICreateExternalTexture(
const ExternalTextureDescriptor* descriptor) {
Ref<ExternalTextureBase> result = nullptr;
if (ConsumedError(CreateExternalTextureInternal(descriptor), &result)) {
if (ConsumedError(CreateExternalTexture(descriptor), &result)) {
return ExternalTextureBase::MakeError(this);
}
@ -1039,7 +1031,7 @@ namespace dawn_native {
// Implementation details of object creation
ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroupInternal(
ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroup(
const BindGroupDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1048,7 +1040,7 @@ namespace dawn_native {
return CreateBindGroupImpl(descriptor);
}
ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::CreateBindGroupLayoutInternal(
ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::CreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1057,8 +1049,7 @@ namespace dawn_native {
return GetOrCreateBindGroupLayout(descriptor);
}
ResultOrError<Ref<BufferBase>> DeviceBase::CreateBufferInternal(
const BufferDescriptor* descriptor) {
ResultOrError<Ref<BufferBase>> DeviceBase::CreateBuffer(const BufferDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
DAWN_TRY(ValidateBufferDescriptor(this, descriptor));
@ -1074,7 +1065,7 @@ namespace dawn_native {
return std::move(buffer);
}
ResultOrError<Ref<ComputePipelineBase>> DeviceBase::CreateComputePipelineInternal(
ResultOrError<Ref<ComputePipelineBase>> DeviceBase::CreateComputePipeline(
const ComputePipelineDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1099,7 +1090,7 @@ namespace dawn_native {
return AddOrGetCachedPipeline(backendObj, blueprintHash);
}
MaybeError DeviceBase::CreateComputePipelineAsyncInternal(
MaybeError DeviceBase::CreateComputePipelineAsync(
const ComputePipelineDescriptor* descriptor,
WGPUCreateComputePipelineAsyncCallback callback,
void* userdata) {
@ -1172,7 +1163,7 @@ namespace dawn_native {
mCreatePipelineAsyncTracker->TrackTask(std::move(request), GetPendingCommandSerial());
}
ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::CreatePipelineLayoutInternal(
ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::CreatePipelineLayout(
const PipelineLayoutDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1181,7 +1172,7 @@ namespace dawn_native {
return GetOrCreatePipelineLayout(descriptor);
}
ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTextureInternal(
ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTexture(
const ExternalTextureDescriptor* descriptor) {
if (IsValidationEnabled()) {
DAWN_TRY(ValidateExternalTextureDescriptor(this, descriptor));
@ -1190,7 +1181,7 @@ namespace dawn_native {
return ExternalTextureBase::Create(this, descriptor);
}
ResultOrError<Ref<QuerySetBase>> DeviceBase::CreateQuerySetInternal(
ResultOrError<Ref<QuerySetBase>> DeviceBase::CreateQuerySet(
const QuerySetDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1199,7 +1190,7 @@ namespace dawn_native {
return CreateQuerySetImpl(descriptor);
}
ResultOrError<Ref<RenderBundleEncoder>> DeviceBase::CreateRenderBundleEncoderInternal(
ResultOrError<Ref<RenderBundleEncoder>> DeviceBase::CreateRenderBundleEncoder(
const RenderBundleEncoderDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1208,7 +1199,7 @@ namespace dawn_native {
return RenderBundleEncoder::Create(this, descriptor);
}
ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateRenderPipelineInternal(
ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateRenderPipeline(
const RenderPipelineDescriptor2* descriptor) {
DAWN_TRY(ValidateIsAlive());
if (IsValidationEnabled()) {
@ -1231,7 +1222,7 @@ namespace dawn_native {
}
}
ResultOrError<Ref<SamplerBase>> DeviceBase::CreateSamplerInternal(
ResultOrError<Ref<SamplerBase>> DeviceBase::CreateSampler(
const SamplerDescriptor* descriptor) {
const SamplerDescriptor defaultDescriptor = {};
DAWN_TRY(ValidateIsAlive());
@ -1242,11 +1233,19 @@ namespace dawn_native {
return GetOrCreateSampler(descriptor);
}
ResultOrError<Ref<ShaderModuleBase>> DeviceBase::CreateShaderModuleInternal(
ResultOrError<Ref<ShaderModuleBase>> DeviceBase::CreateShaderModule(
const ShaderModuleDescriptor* descriptor,
ShaderModuleParseResult* parseResult) {
DAWN_TRY(ValidateIsAlive());
// ShaderModule can be called from inside dawn_native. If that's the case handle the error
// directly in Dawn and don't need the parse results since there should be no validation
// errors.
ShaderModuleParseResult ignoredResults;
if (parseResult == nullptr) {
parseResult = &ignoredResults;
}
if (IsValidationEnabled()) {
DAWN_TRY(ValidateShaderModuleDescriptor(this, descriptor, parseResult));
}
@ -1254,7 +1253,7 @@ namespace dawn_native {
return GetOrCreateShaderModule(descriptor, parseResult);
}
ResultOrError<Ref<SwapChainBase>> DeviceBase::CreateSwapChainInternal(
ResultOrError<Ref<SwapChainBase>> DeviceBase::CreateSwapChain(
Surface* surface,
const SwapChainDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
@ -1285,8 +1284,7 @@ namespace dawn_native {
}
}
ResultOrError<Ref<TextureBase>> DeviceBase::CreateTextureInternal(
const TextureDescriptor* descriptor) {
ResultOrError<Ref<TextureBase>> DeviceBase::CreateTexture(const TextureDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());
TextureDescriptor fixedDescriptor = *descriptor;
DAWN_TRY(FixUpDeprecatedGPUExtent3DDepth(this, &(fixedDescriptor.size)));
@ -1296,7 +1294,7 @@ namespace dawn_native {
return CreateTextureImpl(&fixedDescriptor);
}
ResultOrError<Ref<TextureViewBase>> DeviceBase::CreateTextureViewInternal(
ResultOrError<Ref<TextureViewBase>> DeviceBase::CreateTextureView(
TextureBase* texture,
const TextureViewDescriptor* descriptor) {
DAWN_TRY(ValidateIsAlive());

View File

@ -140,7 +140,40 @@ namespace dawn_native {
Ref<AttachmentState> GetOrCreateAttachmentState(const RenderPassDescriptor* descriptor);
void UncacheAttachmentState(AttachmentState* obj);
// Dawn API
// Object creation methods that be used in a reentrant manner.
ResultOrError<Ref<BindGroupBase>> CreateBindGroup(const BindGroupDescriptor* descriptor);
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor);
ResultOrError<Ref<BufferBase>> CreateBuffer(const BufferDescriptor* descriptor);
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipeline(
const ComputePipelineDescriptor* descriptor);
MaybeError CreateComputePipelineAsync(
const ComputePipelineDescriptor* descriptor,
WGPUCreateComputePipelineAsyncCallback callback,
void* userdata);
ResultOrError<Ref<ExternalTextureBase>> CreateExternalTexture(
const ExternalTextureDescriptor* descriptor);
ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayout(
const PipelineLayoutDescriptor* descriptor);
ResultOrError<Ref<QuerySetBase>> CreateQuerySet(const QuerySetDescriptor* descriptor);
ResultOrError<Ref<RenderBundleEncoder>> CreateRenderBundleEncoder(
const RenderBundleEncoderDescriptor* descriptor);
ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipeline(
const RenderPipelineDescriptor2* descriptor);
ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipeline(
const RenderPipelineDescriptor* descriptor);
ResultOrError<Ref<SamplerBase>> CreateSampler(const SamplerDescriptor* descriptor);
ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(
const ShaderModuleDescriptor* descriptor,
ShaderModuleParseResult* parseResult = nullptr);
ResultOrError<Ref<SwapChainBase>> CreateSwapChain(Surface* surface,
const SwapChainDescriptor* descriptor);
ResultOrError<Ref<TextureBase>> CreateTexture(const TextureDescriptor* descriptor);
ResultOrError<Ref<TextureViewBase>> CreateTextureView(
TextureBase* texture,
const TextureViewDescriptor* descriptor);
// Implementation of API object creation methods. DO NOT use them in a reentrant manner.
BindGroupBase* APICreateBindGroup(const BindGroupDescriptor* descriptor);
BindGroupLayoutBase* APICreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
BufferBase* APICreateBuffer(const BufferDescriptor* descriptor);
@ -163,8 +196,7 @@ namespace dawn_native {
ShaderModuleBase* APICreateShaderModule(const ShaderModuleDescriptor* descriptor);
SwapChainBase* APICreateSwapChain(Surface* surface, const SwapChainDescriptor* descriptor);
TextureBase* APICreateTexture(const TextureDescriptor* descriptor);
TextureViewBase* CreateTextureView(TextureBase* texture,
const TextureViewDescriptor* descriptor);
InternalPipelineStore* GetInternalPipelineStore();
// For Dawn Wire
@ -299,39 +331,6 @@ namespace dawn_native {
ResultOrError<Ref<BindGroupLayoutBase>> CreateEmptyBindGroupLayout();
ResultOrError<Ref<BindGroupBase>> CreateBindGroupInternal(
const BindGroupDescriptor* descriptor);
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutInternal(
const BindGroupLayoutDescriptor* descriptor);
ResultOrError<Ref<BufferBase>> CreateBufferInternal(const BufferDescriptor* descriptor);
MaybeError CreateComputePipelineAsyncInternal(
const ComputePipelineDescriptor* descriptor,
WGPUCreateComputePipelineAsyncCallback callback,
void* userdata);
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineInternal(
const ComputePipelineDescriptor* descriptor);
ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutInternal(
const PipelineLayoutDescriptor* descriptor);
ResultOrError<Ref<ExternalTextureBase>> CreateExternalTextureInternal(
const ExternalTextureDescriptor* descriptor);
ResultOrError<Ref<QuerySetBase>> CreateQuerySetInternal(
const QuerySetDescriptor* descriptor);
ResultOrError<Ref<RenderBundleEncoder>> CreateRenderBundleEncoderInternal(
const RenderBundleEncoderDescriptor* descriptor);
ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipelineInternal(
const RenderPipelineDescriptor2* descriptor);
ResultOrError<Ref<SamplerBase>> CreateSamplerInternal(const SamplerDescriptor* descriptor);
ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleInternal(
const ShaderModuleDescriptor* descriptor,
ShaderModuleParseResult* parseResult);
ResultOrError<Ref<SwapChainBase>> CreateSwapChainInternal(
Surface* surface,
const SwapChainDescriptor* descriptor);
ResultOrError<Ref<TextureBase>> CreateTextureInternal(const TextureDescriptor* descriptor);
ResultOrError<Ref<TextureViewBase>> CreateTextureViewInternal(
TextureBase* texture,
const TextureViewDescriptor* descriptor);
ResultOrError<Ref<PipelineLayoutBase>> ValidateAndGetComputePipelineDescriptorWithDefaults(
const ComputePipelineDescriptor& descriptor,
ComputePipelineDescriptor* outDescriptor);

View File

@ -125,21 +125,24 @@ namespace dawn_native {
return {};
}
BindGroupLayoutBase* PipelineBase::APIGetBindGroupLayout(uint32_t groupIndexIn) {
if (GetDevice()->ConsumedError(ValidateGetBindGroupLayout(groupIndexIn))) {
return BindGroupLayoutBase::MakeError(GetDevice());
}
ResultOrError<Ref<BindGroupLayoutBase>> PipelineBase::GetBindGroupLayout(
uint32_t groupIndexIn) {
DAWN_TRY(ValidateGetBindGroupLayout(groupIndexIn));
BindGroupIndex groupIndex(groupIndexIn);
BindGroupLayoutBase* bgl = nullptr;
if (!mLayout->GetBindGroupLayoutsMask()[groupIndex]) {
bgl = GetDevice()->GetEmptyBindGroupLayout();
return Ref<BindGroupLayoutBase>(GetDevice()->GetEmptyBindGroupLayout());
} else {
bgl = mLayout->GetBindGroupLayout(groupIndex);
return Ref<BindGroupLayoutBase>(mLayout->GetBindGroupLayout(groupIndex));
}
bgl->Reference();
return bgl;
}
BindGroupLayoutBase* PipelineBase::APIGetBindGroupLayout(uint32_t groupIndexIn) {
Ref<BindGroupLayoutBase> result;
if (GetDevice()->ConsumedError(GetBindGroupLayout(groupIndexIn), &result)) {
return BindGroupLayoutBase::MakeError(GetDevice());
}
return result.Detach();
}
size_t PipelineBase::ComputeContentHash() {

View File

@ -50,12 +50,15 @@ namespace dawn_native {
const ProgrammableStage& GetStage(SingleShaderStage stage) const;
const PerStage<ProgrammableStage>& GetAllStages() const;
BindGroupLayoutBase* APIGetBindGroupLayout(uint32_t groupIndex);
ResultOrError<Ref<BindGroupLayoutBase>> GetBindGroupLayout(uint32_t groupIndex);
// Helper functions for std::unordered_map-based pipeline caches.
size_t ComputeContentHash() override;
static bool EqualForCache(const PipelineBase* a, const PipelineBase* b);
// Implementation of the API entrypoint. Do not use in a reentrant manner.
BindGroupLayoutBase* APIGetBindGroupLayout(uint32_t groupIndex);
protected:
PipelineBase(DeviceBase* device,
PipelineLayoutBase* layout,

View File

@ -105,7 +105,8 @@ namespace dawn_native {
}
)";
ComputePipelineBase* GetOrCreateTimestampComputePipeline(DeviceBase* device) {
ResultOrError<ComputePipelineBase*> GetOrCreateTimestampComputePipeline(
DeviceBase* device) {
InternalPipelineStore* store = device->GetInternalPipelineStore();
if (store->timestampComputePipeline == nullptr) {
@ -116,8 +117,7 @@ namespace dawn_native {
wgslDesc.source = sConvertTimestampsToNanoseconds;
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
store->timestampCS = AcquireRef(device->APICreateShaderModule(&descriptor));
DAWN_TRY_ASSIGN(store->timestampCS, device->CreateShaderModule(&descriptor));
}
// Create ComputePipeline.
@ -127,9 +127,8 @@ namespace dawn_native {
computePipelineDesc.computeStage.module = store->timestampCS.Get();
computePipelineDesc.computeStage.entryPoint = "main";
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
store->timestampComputePipeline =
AcquireRef(device->APICreateComputePipeline(&computePipelineDesc));
DAWN_TRY_ASSIGN(store->timestampComputePipeline,
device->CreateComputePipeline(&computePipelineDesc));
}
return store->timestampComputePipeline.Get();
@ -137,17 +136,18 @@ namespace dawn_native {
} // anonymous namespace
void EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
BufferBase* timestamps,
BufferBase* availability,
BufferBase* params) {
MaybeError EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
BufferBase* timestamps,
BufferBase* availability,
BufferBase* params) {
DeviceBase* device = encoder->GetDevice();
ComputePipelineBase* pipeline = GetOrCreateTimestampComputePipeline(device);
ComputePipelineBase* pipeline;
DAWN_TRY_ASSIGN(pipeline, GetOrCreateTimestampComputePipeline(device));
// Prepare bind group layout.
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BindGroupLayoutBase> layout = AcquireRef(pipeline->APIGetBindGroupLayout(0));
Ref<BindGroupLayoutBase> layout;
DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));
// Prepare bind group descriptor
std::array<BindGroupEntry, 3> bindGroupEntries = {};
@ -168,8 +168,8 @@ namespace dawn_native {
bindGroupEntries[2].size = params->GetSize();
// Create bind group after all binding entries are set.
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<BindGroupBase> bindGroup = AcquireRef(device->APICreateBindGroup(&bgDesc));
Ref<BindGroupBase> bindGroup;
DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bgDesc));
// Create compute encoder and issue dispatch.
ComputePassDescriptor passDesc = {};
@ -180,6 +180,8 @@ namespace dawn_native {
pass->APIDispatch(
static_cast<uint32_t>((timestamps->GetSize() / sizeof(uint64_t) + 7) / 8));
pass->APIEndPass();
return {};
}
} // namespace dawn_native

View File

@ -15,6 +15,7 @@
#ifndef DAWNNATIVE_QUERYHELPER_H_
#define DAWNNATIVE_QUERYHELPER_H_
#include "dawn_native/Error.h"
#include "dawn_native/ObjectBase.h"
namespace dawn_native {
@ -28,10 +29,10 @@ namespace dawn_native {
float period;
};
void EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
BufferBase* timestamps,
BufferBase* availability,
BufferBase* params);
MaybeError EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
BufferBase* timestamps,
BufferBase* availability,
BufferBase* params);
} // namespace dawn_native

View File

@ -626,7 +626,13 @@ namespace dawn_native {
}
TextureViewBase* TextureBase::APICreateView(const TextureViewDescriptor* descriptor) {
return GetDevice()->CreateTextureView(this, descriptor);
DeviceBase* device = GetDevice();
Ref<TextureViewBase> result;
if (device->ConsumedError(device->CreateTextureView(this, descriptor), &result)) {
return TextureViewBase::MakeError(device);
}
return result.Detach();
}
void TextureBase::APIDestroy() {

View File

@ -126,6 +126,12 @@ namespace dawn_native {
common);
}
template <typename BackendTraits, typename T>
Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&& ToBackendBase(Ref<T>&& common) {
return reinterpret_cast<Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&&>(
common);
}
template <typename BackendTraits, typename T>
const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(
const Ref<T>& common) {

View File

@ -139,10 +139,10 @@ namespace dawn_native { namespace d3d12 {
return false;
}
void RecordCopyTextureWithTemporaryBuffer(CommandRecordingContext* recordingContext,
const TextureCopy& srcCopy,
const TextureCopy& dstCopy,
const Extent3D& copySize) {
MaybeError RecordCopyTextureWithTemporaryBuffer(CommandRecordingContext* recordingContext,
const TextureCopy& srcCopy,
const TextureCopy& dstCopy,
const Extent3D& copySize) {
ASSERT(srcCopy.texture->GetFormat().format == dstCopy.texture->GetFormat().format);
ASSERT(srcCopy.aspect == dstCopy.aspect);
dawn_native::Format format = srcCopy.texture->GetFormat();
@ -166,9 +166,9 @@ namespace dawn_native { namespace d3d12 {
tempBufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
tempBufferDescriptor.size = tempBufferSize.AcquireSuccess();
Device* device = ToBackend(srcCopy.texture->GetDevice());
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
Ref<Buffer> tempBuffer =
AcquireRef(ToBackend(device->APICreateBuffer(&tempBufferDescriptor)));
Ref<BufferBase> tempBufferBase;
DAWN_TRY_ASSIGN(tempBufferBase, device->CreateBuffer(&tempBufferDescriptor));
Ref<Buffer> tempBuffer = ToBackend(std::move(tempBufferBase));
// Copy from source texture into tempBuffer
Texture* srcTexture = ToBackend(srcCopy.texture).Get();
@ -190,6 +190,8 @@ namespace dawn_native { namespace d3d12 {
// Save tempBuffer into recordingContext
recordingContext->AddToTempBuffers(std::move(tempBuffer));
return {};
}
} // anonymous namespace
@ -824,8 +826,8 @@ namespace dawn_native { namespace d3d12 {
ASSERT(srcRange.aspects == dstRange.aspects);
if (ShouldCopyUsingTemporaryBuffer(GetDevice(), copy->source,
copy->destination)) {
RecordCopyTextureWithTemporaryBuffer(commandContext, copy->source,
copy->destination, copy->copySize);
DAWN_TRY(RecordCopyTextureWithTemporaryBuffer(
commandContext, copy->source, copy->destination, copy->copySize));
break;
}

View File

@ -25,11 +25,11 @@ namespace {
wgpu::Buffer timestamps,
wgpu::Buffer availability,
wgpu::Buffer params) {
dawn_native::EncodeConvertTimestampsToNanoseconds(
ASSERT_TRUE(dawn_native::EncodeConvertTimestampsToNanoseconds(
reinterpret_cast<dawn_native::CommandEncoder*>(encoder.Get()),
reinterpret_cast<dawn_native::BufferBase*>(timestamps.Get()),
reinterpret_cast<dawn_native::BufferBase*>(availability.Get()),
reinterpret_cast<dawn_native::BufferBase*>(params.Get()));
reinterpret_cast<dawn_native::BufferBase*>(params.Get())).IsSuccess());
}
class InternalShaderExpectation : public detail::Expectation {