| /* | |
| * Copyright 2020 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "src/gpu/d3d/GrD3DTexture.h" | |
| #include "src/gpu/GrTexture.h" | |
| #include "src/gpu/d3d/GrD3DGpu.h" | |
| #include "src/gpu/d3d/GrD3DUtil.h" | |
| #include "include/gpu/d3d/GrD3DTypes.h" | |
| // Because this class is virtually derived from GrSurface we must explicitly call its constructor. | |
| GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu, | |
| SkBudgeted budgeted, | |
| SkISize dimensions, | |
| const GrD3DTextureResourceInfo& info, | |
| sk_sp<GrD3DResourceState> state, | |
| const GrD3DDescriptorHeap::CPUHandle& shaderResourceView, | |
| GrMipmapStatus mipmapStatus) | |
| : GrSurface(gpu, dimensions, info.fProtected) | |
| , GrD3DTextureResource(info, std::move(state)) | |
| , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus) | |
| , fShaderResourceView(shaderResourceView) { | |
| SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount)); | |
| this->registerWithCache(budgeted); | |
| if (GrDxgiFormatIsCompressed(info.fFormat)) { | |
| this->setReadOnly(); | |
| } | |
| } | |
| GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu, SkISize dimensions, const GrD3DTextureResourceInfo& info, | |
| sk_sp<GrD3DResourceState> state, | |
| const GrD3DDescriptorHeap::CPUHandle& shaderResourceView, | |
| GrMipmapStatus mipmapStatus, GrWrapCacheable cacheable, | |
| GrIOType ioType) | |
| : GrSurface(gpu, dimensions, info.fProtected) | |
| , GrD3DTextureResource(info, std::move(state)) | |
| , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus) | |
| , fShaderResourceView(shaderResourceView) { | |
| SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount)); | |
| if (ioType == kRead_GrIOType) { | |
| this->setReadOnly(); | |
| } | |
| this->registerWithCacheWrapped(cacheable); | |
| } | |
| // Because this class is virtually derived from GrSurface we must explicitly call its constructor. | |
| GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu, | |
| SkISize dimensions, | |
| const GrD3DTextureResourceInfo& info, | |
| sk_sp<GrD3DResourceState> state, | |
| const GrD3DDescriptorHeap::CPUHandle& shaderResourceView, | |
| GrMipmapStatus mipmapStatus) | |
| : GrSurface(gpu, dimensions, info.fProtected) | |
| , GrD3DTextureResource(info, state) | |
| , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus) | |
| , fShaderResourceView(shaderResourceView) { | |
| SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount)); | |
| } | |
| sk_sp<GrD3DTexture> GrD3DTexture::MakeNewTexture(GrD3DGpu* gpu, SkBudgeted budgeted, | |
| SkISize dimensions, | |
| const D3D12_RESOURCE_DESC& desc, | |
| GrProtected isProtected, | |
| GrMipmapStatus mipmapStatus) { | |
| GrD3DTextureResourceInfo info; | |
| if (!GrD3DTextureResource::InitTextureResourceInfo(gpu, desc, | |
| D3D12_RESOURCE_STATE_COPY_DEST, | |
| isProtected, nullptr, &info)) { | |
| return nullptr; | |
| } | |
| sk_sp<GrD3DResourceState> state( | |
| new GrD3DResourceState(static_cast<D3D12_RESOURCE_STATES>(info.fResourceState))); | |
| GrD3DDescriptorHeap::CPUHandle shaderResourceView = | |
| gpu->resourceProvider().createShaderResourceView(info.fResource.get()); | |
| GrD3DTexture* tex = new GrD3DTexture(gpu, budgeted, dimensions, info, std::move(state), | |
| shaderResourceView, mipmapStatus); | |
| return sk_sp<GrD3DTexture>(tex); | |
| } | |
| sk_sp<GrD3DTexture> GrD3DTexture::MakeWrappedTexture(GrD3DGpu* gpu, | |
| SkISize dimensions, | |
| GrWrapCacheable cacheable, | |
| GrIOType ioType, | |
| const GrD3DTextureResourceInfo& info, | |
| sk_sp<GrD3DResourceState> state) { | |
| // TODO: If a client uses their own heap to allocate, how do we manage that? | |
| // Adopted textures require both image and allocation because we're responsible for freeing | |
| //SkASSERT(info.fTexture && | |
| // (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory)); | |
| GrMipmapStatus mipmapStatus = info.fLevelCount > 1 ? GrMipmapStatus::kValid | |
| : GrMipmapStatus::kNotAllocated; | |
| GrD3DDescriptorHeap::CPUHandle shaderResourceView = | |
| gpu->resourceProvider().createShaderResourceView(info.fResource.get()); | |
| return sk_sp<GrD3DTexture>(new GrD3DTexture(gpu, dimensions, info, std::move(state), | |
| shaderResourceView, mipmapStatus, cacheable, | |
| ioType)); | |
| } | |
| sk_sp<GrD3DTexture> GrD3DTexture::MakeAliasingTexture(GrD3DGpu* gpu, | |
| sk_sp<GrD3DTexture> originalTexture, | |
| DXGI_FORMAT format) { | |
| GrD3DTextureResourceInfo info = originalTexture->fInfo; | |
| D3D12_RESOURCE_DESC desc = originalTexture->d3dResource()->GetDesc(); | |
| desc.Format = format; | |
| info.fResource = gpu->memoryAllocator()->createAliasingResource(info.fAlloc, 0, &desc, | |
| info.fResourceState, nullptr); | |
| if (!info.fResource) { | |
| return false; | |
| } | |
| sk_sp<GrD3DResourceState> state( | |
| new GrD3DResourceState(static_cast<D3D12_RESOURCE_STATES>(info.fResourceState))); | |
| GrD3DDescriptorHeap::CPUHandle shaderResourceView = | |
| gpu->resourceProvider().createShaderResourceView(info.fResource.get()); | |
| GrD3DTexture* tex = new GrD3DTexture(gpu, SkBudgeted::kNo, originalTexture->dimensions(), | |
| info, std::move(state), shaderResourceView, | |
| originalTexture->mipmapStatus()); | |
| return sk_sp<GrD3DTexture>(tex); | |
| } | |
| void GrD3DTexture::onRelease() { | |
| GrD3DGpu* gpu = this->getD3DGpu(); | |
| gpu->resourceProvider().recycleShaderView(fShaderResourceView); | |
| this->releaseResource(gpu); | |
| INHERITED::onRelease(); | |
| } | |
| void GrD3DTexture::onAbandon() { | |
| GrD3DGpu* gpu = this->getD3DGpu(); | |
| gpu->resourceProvider().recycleShaderView(fShaderResourceView); | |
| this->releaseResource(gpu); | |
| INHERITED::onAbandon(); | |
| } | |
| GrBackendTexture GrD3DTexture::getBackendTexture() const { | |
| return GrBackendTexture(this->width(), this->height(), fInfo, this->grD3DResourceState()); | |
| } | |
| GrD3DGpu* GrD3DTexture::getD3DGpu() const { | |
| SkASSERT(!this->wasDestroyed()); | |
| return static_cast<GrD3DGpu*>(this->getGpu()); | |
| } |