blob: 1fdf7d6c4916e1fbd18abf761e214d3e7bbe5e85 [file] [log] [blame]
// Copyright 2022 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/ExternalImageDXGIImpl.h"
#include <d3d12.h>
#include <utility>
#include "dawn/common/Log.h"
#include "dawn/native/D3D12Backend.h"
#include "dawn/native/DawnNative.h"
#include "dawn/native/d3d12/D3D11on12Util.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
namespace dawn::native::d3d12 {
ExternalImageDXGIImpl::ExternalImageDXGIImpl(Device* backendDevice,
Microsoft::WRL::ComPtr<ID3D12Resource> d3d12Resource,
Microsoft::WRL::ComPtr<ID3D12Fence> d3d12Fence,
const WGPUTextureDescriptor* descriptor)
: mBackendDevice(backendDevice),
mD3D12Resource(std::move(d3d12Resource)),
mD3D12Fence(std::move(d3d12Fence)),
mD3D11on12ResourceCache(std::make_unique<D3D11on12ResourceCache>()),
mUsage(descriptor->usage),
mDimension(descriptor->dimension),
mSize(descriptor->size),
mFormat(descriptor->format),
mMipLevelCount(descriptor->mipLevelCount),
mSampleCount(descriptor->sampleCount) {
ASSERT(mBackendDevice != nullptr);
ASSERT(mD3D12Resource != nullptr);
ASSERT(!descriptor->nextInChain ||
descriptor->nextInChain->sType == WGPUSType_DawnTextureInternalUsageDescriptor);
if (descriptor->nextInChain) {
mUsageInternal =
reinterpret_cast<const WGPUDawnTextureInternalUsageDescriptor*>(descriptor->nextInChain)
->internalUsage;
}
}
ExternalImageDXGIImpl::~ExternalImageDXGIImpl() {
Destroy();
}
bool ExternalImageDXGIImpl::IsValid() const {
return IsInList();
}
void ExternalImageDXGIImpl::Destroy() {
if (IsInList()) {
RemoveFromList();
// Keep fence alive until any pending signal calls are done on the GPU.
mBackendDevice->ConsumedError(mBackendDevice->NextSerial());
mBackendDevice->ReferenceUntilUnused(mD3D12Fence.Get());
mBackendDevice = nullptr;
mD3D12Resource.Reset();
mD3D12Fence.Reset();
mD3D11on12ResourceCache.reset();
}
}
WGPUTexture ExternalImageDXGIImpl::ProduceTexture(
const ExternalImageAccessDescriptorDXGISharedHandle* descriptor) {
ASSERT(mBackendDevice != nullptr);
// Ensure the texture usage is allowed
if (!IsSubset(descriptor->usage, mUsage)) {
dawn::ErrorLog() << "Texture usage is not valid for external image";
return nullptr;
}
TextureDescriptor textureDescriptor = {};
textureDescriptor.usage = static_cast<wgpu::TextureUsage>(descriptor->usage);
textureDescriptor.dimension = static_cast<wgpu::TextureDimension>(mDimension);
textureDescriptor.size = {mSize.width, mSize.height, mSize.depthOrArrayLayers};
textureDescriptor.format = static_cast<wgpu::TextureFormat>(mFormat);
textureDescriptor.mipLevelCount = mMipLevelCount;
textureDescriptor.sampleCount = mSampleCount;
DawnTextureInternalUsageDescriptor internalDesc = {};
if (mUsageInternal) {
textureDescriptor.nextInChain = &internalDesc;
internalDesc.internalUsage = static_cast<wgpu::TextureUsage>(mUsageInternal);
internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;
}
Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource;
if (!mD3D12Fence) {
d3d11on12Resource = mD3D11on12ResourceCache->GetOrCreateD3D11on12Resource(
mBackendDevice, mD3D12Resource.Get());
if (d3d11on12Resource == nullptr) {
dawn::ErrorLog() << "Unable to create 11on12 resource for external image";
return nullptr;
}
}
Ref<TextureBase> texture = mBackendDevice->CreateD3D12ExternalTexture(
&textureDescriptor, mD3D12Resource, mD3D12Fence, std::move(d3d11on12Resource),
descriptor->fenceWaitValue, descriptor->fenceSignalValue, descriptor->isSwapChainTexture,
descriptor->isInitialized);
return ToAPI(texture.Detach());
}
} // namespace dawn::native::d3d12