Fill in the D3DTexture class.
Bug: skia:9935 Change-Id: Idd37e677462fec7ed0beca0fe578fb1a2f497eb8 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/278784 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
7a5f1fa1fb
commit
8b932b157b
@ -743,11 +743,13 @@ skia_direct3d_sources = [
|
||||
"$_src/gpu/d3d/GrD3DGpu.h",
|
||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.cpp",
|
||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.h",
|
||||
"$_src/gpu/d3d/GrD3DResource.cpp",
|
||||
"$_src/gpu/d3d/GrD3DResource.h",
|
||||
"$_src/gpu/d3d/GrD3DResourceProvider.cpp",
|
||||
"$_src/gpu/d3d/GrD3DResourceProvider.h",
|
||||
"$_src/gpu/d3d/GrD3DResourceState.h",
|
||||
"$_src/gpu/d3d/GrD3DSurfaceResource.cpp",
|
||||
"$_src/gpu/d3d/GrD3DSurfaceResource.h",
|
||||
"$_src/gpu/d3d/GrD3DTexture.cpp",
|
||||
"$_src/gpu/d3d/GrD3DTexture.h",
|
||||
"$_src/gpu/d3d/GrD3DTypesPriv.cpp",
|
||||
"$_src/gpu/d3d/GrD3DUtil.cpp",
|
||||
"$_src/gpu/d3d/GrD3DUtil.h",
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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/GrGpuResourcePriv.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DResource.h"
|
||||
|
||||
void GrD3DResource::setResourceState(const GrD3DGpu* gpu,
|
||||
D3D12_RESOURCE_STATES newResourceState) {
|
||||
SkASSERT(fStateExplicitlySet);
|
||||
/* TODO
|
||||
* Something like:
|
||||
D3D12_RESOURCE_STATES currentState = this->currentState();
|
||||
gpu->addResourceTransitionBarrier(this->resource(), currentState, newResourceState);
|
||||
*/
|
||||
this->updateResourceState(newResourceState, true);
|
||||
}
|
||||
|
||||
ID3D12Resource* GrD3DResource::CreateResource(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc,
|
||||
D3D12_RESOURCE_STATES resourceState) {
|
||||
ID3D12Resource* resource = nullptr;
|
||||
|
||||
// TODO: incorporate D3Dx12.h and use CD3DX12_HEAP_PROPERTIES instead?
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {
|
||||
D3D12_HEAP_TYPE_DEFAULT,
|
||||
D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
D3D12_MEMORY_POOL_UNKNOWN,
|
||||
1, // CreationNodeMask
|
||||
1 // VisibleNodeMask
|
||||
};
|
||||
SkDEBUGCODE(HRESULT hr =) gpu->device()->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
resourceState,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&resource));
|
||||
SkASSERT(SUCCEEDED(hr));
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
GrD3DResource::~GrD3DResource() {
|
||||
// should have been released first
|
||||
SkASSERT(!fResource);
|
||||
}
|
||||
|
||||
void GrD3DResource::releaseResource() {
|
||||
if (fResource) {
|
||||
fResource->Release();
|
||||
fResource = nullptr;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrD3DResource_DEFINED
|
||||
#define GrD3DResource_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/private/GrTypesPriv.h"
|
||||
#include "src/gpu/d3d/GrD3D12.h"
|
||||
#include "src/gpu/d3d/GrD3DResourceState.h"
|
||||
|
||||
class GrD3DGpu;
|
||||
|
||||
class GrD3DResource : SkNoncopyable {
|
||||
public:
|
||||
GrD3DResource(ID3D12Resource* resource, const D3D12_RESOURCE_DESC& desc,
|
||||
sk_sp<GrD3DResourceState> state,
|
||||
GrBackendObjectOwnership ownership = GrBackendObjectOwnership::kOwned)
|
||||
: fDesc(desc)
|
||||
, fState(std::move(state))
|
||||
, fStateExplicitlySet(true)
|
||||
, fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership)
|
||||
, fResource(resource) {
|
||||
if (fIsBorrowed) {
|
||||
fResource->AddRef();
|
||||
}
|
||||
}
|
||||
virtual ~GrD3DResource();
|
||||
|
||||
const ID3D12Resource* resource() const {
|
||||
SkASSERT(fResource);
|
||||
return fResource;
|
||||
}
|
||||
DXGI_FORMAT dxgiFormat() const { return fDesc.Format; }
|
||||
GrBackendFormat getBackendFormat() const {
|
||||
return GrBackendFormat::MakeDxgi(this->dxgiFormat());
|
||||
}
|
||||
uint32_t mipLevels() const { return fDesc.MipLevels; }
|
||||
bool isBorrowed() const { return fIsBorrowed; }
|
||||
|
||||
sk_sp<GrD3DResourceState> grD3DResourceState() const { return fState; }
|
||||
|
||||
D3D12_RESOURCE_STATES currentState() const {
|
||||
return fState->getResourceState();
|
||||
}
|
||||
|
||||
void setResourceState(const GrD3DGpu* gpu,
|
||||
D3D12_RESOURCE_STATES newResourceState);
|
||||
|
||||
// This simply updates our tracking of the resourceState and does not actually do any gpu work.
|
||||
// Externally, primarily used for implicit changes in resourceState due to certain GPU commands.
|
||||
void updateResourceState(D3D12_RESOURCE_STATES newState, bool explicitlySet) {
|
||||
SkASSERT(fResource);
|
||||
fState->setResourceState(newState);
|
||||
}
|
||||
|
||||
static ID3D12Resource* CreateResource(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc,
|
||||
D3D12_RESOURCE_STATES resourceState);
|
||||
|
||||
protected:
|
||||
void releaseResource();
|
||||
bool hasResource() const { return SkToBool(fResource); }
|
||||
|
||||
D3D12_RESOURCE_DESC fDesc;
|
||||
sk_sp<GrD3DResourceState> fState;
|
||||
bool fStateExplicitlySet;
|
||||
bool fIsBorrowed;
|
||||
|
||||
private:
|
||||
ID3D12Resource* fResource;
|
||||
};
|
||||
|
||||
#endif
|
93
src/gpu/d3d/GrD3DSurfaceResource.cpp
Normal file
93
src/gpu/d3d/GrD3DSurfaceResource.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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/GrGpuResourcePriv.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DSurfaceResource.h"
|
||||
|
||||
void GrD3DSurfaceResource::setResourceState(const GrD3DGpu* gpu,
|
||||
D3D12_RESOURCE_STATES newResourceState) {
|
||||
SkASSERT(fStateExplicitlySet);
|
||||
/* TODO
|
||||
* Something like:
|
||||
D3D12_RESOURCE_STATES currentState = this->currentState();
|
||||
gpu->addResourceTransitionBarrier(this->resource(), currentState, newResourceState);
|
||||
*/
|
||||
this->updateResourceState(newResourceState, true);
|
||||
}
|
||||
|
||||
bool GrD3DSurfaceResource::InitTextureInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc,
|
||||
GrProtected isProtected, GrD3DTextureInfo* info) {
|
||||
if (0 == desc.Width || 0 == desc.Height) {
|
||||
return false;
|
||||
}
|
||||
// TODO: We don't support protected memory at the moment
|
||||
if (isProtected == GrProtected::kYes) {
|
||||
return false;
|
||||
}
|
||||
// If MipLevels is 0, for some formats the API will automatically calculate the maximum
|
||||
// number of levels supported and use that -- we don't support that.
|
||||
SkASSERT(desc.MipLevels > 0);
|
||||
|
||||
ID3D12Resource* resource = nullptr;
|
||||
|
||||
// TODO: incorporate D3Dx12.h and use CD3DX12_HEAP_PROPERTIES instead?
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {
|
||||
D3D12_HEAP_TYPE_DEFAULT,
|
||||
D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
D3D12_MEMORY_POOL_UNKNOWN,
|
||||
1, // CreationNodeMask
|
||||
1 // VisibleNodeMask
|
||||
};
|
||||
HRESULT hr = gpu->device()->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&resource));
|
||||
if (!SUCCEEDED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
info->fTexture = resource;
|
||||
info->fResourceState = D3D12_RESOURCE_STATE_COMMON;
|
||||
info->fFormat = desc.Format;
|
||||
info->fLevelCount = desc.MipLevels;
|
||||
info->fProtected = isProtected;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrD3DSurfaceResource::DestroyTextureInfo(GrD3DTextureInfo* info) {
|
||||
info->fTexture->Release();
|
||||
}
|
||||
|
||||
GrD3DSurfaceResource::~GrD3DSurfaceResource() {
|
||||
// should have been released first
|
||||
SkASSERT(!fResource);
|
||||
}
|
||||
|
||||
void GrD3DSurfaceResource::releaseTexture(GrD3DGpu* gpu) {
|
||||
// TODO: do we need to migrate resource state if we change queues?
|
||||
if (fResource) {
|
||||
fResource->removeOwningTexture();
|
||||
fResource->unref();
|
||||
fResource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GrD3DSurfaceResource::setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper) {
|
||||
SkASSERT(fResource);
|
||||
// Forward the release proc on to GrD3DSurfaceResource::Resource
|
||||
fResource->setRelease(std::move(releaseHelper));
|
||||
}
|
||||
|
||||
void GrD3DSurfaceResource::Resource::freeGPUData() const {
|
||||
this->invokeReleaseProc();
|
||||
fResource->Release();
|
||||
}
|
112
src/gpu/d3d/GrD3DSurfaceResource.h
Normal file
112
src/gpu/d3d/GrD3DSurfaceResource.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrD3DSurfaceResource_DEFINED
|
||||
#define GrD3DSurfaceResource_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/private/GrTypesPriv.h"
|
||||
#include "src/gpu/GrManagedResource.h"
|
||||
#include "src/gpu/d3d/GrD3D12.h"
|
||||
#include "src/gpu/d3d/GrD3DResourceState.h"
|
||||
|
||||
class GrD3DGpu;
|
||||
|
||||
class GrD3DSurfaceResource : SkNoncopyable {
|
||||
private:
|
||||
class Resource;
|
||||
|
||||
public:
|
||||
GrD3DSurfaceResource(const GrD3DTextureInfo& info, sk_sp<GrD3DResourceState> state,
|
||||
GrBackendObjectOwnership ownership = GrBackendObjectOwnership::kOwned)
|
||||
: fInfo(info)
|
||||
, fState(std::move(state))
|
||||
, fStateExplicitlySet(true)
|
||||
, fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership)
|
||||
, fResource(new Resource(fInfo.fTexture)) {
|
||||
if (fIsBorrowed) {
|
||||
fInfo.fTexture->AddRef();
|
||||
}
|
||||
}
|
||||
virtual ~GrD3DSurfaceResource();
|
||||
|
||||
const Resource* resource() const {
|
||||
SkASSERT(fResource);
|
||||
return fResource.get();
|
||||
}
|
||||
DXGI_FORMAT dxgiFormat() const { return fInfo.fFormat; }
|
||||
GrBackendFormat getBackendFormat() const {
|
||||
return GrBackendFormat::MakeDxgi(this->dxgiFormat());
|
||||
}
|
||||
uint32_t mipLevels() const { return fInfo.fLevelCount; }
|
||||
bool isBorrowed() const { return fIsBorrowed; }
|
||||
|
||||
sk_sp<GrD3DResourceState> grD3DResourceState() const { return fState; }
|
||||
|
||||
D3D12_RESOURCE_STATES currentState() const {
|
||||
return fState->getResourceState();
|
||||
}
|
||||
|
||||
void setResourceState(const GrD3DGpu* gpu, D3D12_RESOURCE_STATES newResourceState);
|
||||
|
||||
// This simply updates our tracking of the resourceState and does not actually do any gpu work.
|
||||
// Externally, primarily used for implicit changes in resourceState due to certain GPU commands.
|
||||
void updateResourceState(D3D12_RESOURCE_STATES newState, bool explicitlySet) {
|
||||
SkASSERT(fResource);
|
||||
fState->setResourceState(newState);
|
||||
fStateExplicitlySet = explicitlySet;
|
||||
}
|
||||
|
||||
static bool InitTextureInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc, GrProtected,
|
||||
GrD3DTextureInfo*);
|
||||
// Destroys the internal ID3D12Resource in the GrD3DTextureInfo
|
||||
static void DestroyTextureInfo(GrD3DTextureInfo*);
|
||||
|
||||
void setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper);
|
||||
|
||||
protected:
|
||||
void releaseTexture(GrD3DGpu* gpu);
|
||||
bool hasResource() const { return SkToBool(fResource); }
|
||||
|
||||
GrD3DTextureInfo fInfo;
|
||||
sk_sp<GrD3DResourceState> fState;
|
||||
bool fStateExplicitlySet;
|
||||
bool fIsBorrowed;
|
||||
|
||||
private:
|
||||
class Resource : public GrTextureResource {
|
||||
public:
|
||||
explicit Resource()
|
||||
: fResource(nullptr) {
|
||||
}
|
||||
|
||||
Resource(ID3D12Resource* textureResource)
|
||||
: fResource(textureResource) {
|
||||
fResource->AddRef();
|
||||
}
|
||||
|
||||
~Resource() override {}
|
||||
|
||||
#ifdef SK_TRACE_MANAGED_RESOURCES
|
||||
void dumpInfo() const override {
|
||||
SkDebugf("GrD3DSurfaceResource: %d (%d refs)\n", fResource, this->getRefCnt());
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void freeGPUData() const override;
|
||||
|
||||
ID3D12Resource* fResource;
|
||||
|
||||
typedef GrTextureResource INHERITED;
|
||||
};
|
||||
|
||||
sk_sp<Resource> fResource;
|
||||
};
|
||||
|
||||
#endif
|
198
src/gpu/d3d/GrD3DTexture.cpp
Normal file
198
src/gpu/d3d/GrD3DTexture.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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/GrTexturePriv.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 GrD3DTextureInfo& info,
|
||||
sk_sp<GrD3DResourceState> state,
|
||||
GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, dimensions, info.fProtected)
|
||||
, GrD3DSurfaceResource(info, std::move(state), GrBackendObjectOwnership::kOwned)
|
||||
, INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipMapsStatus) {
|
||||
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == info.fLevelCount));
|
||||
this->registerWithCache(budgeted);
|
||||
if (GrDxgiFormatIsCompressed(info.fFormat)) {
|
||||
this->setReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu, SkISize dimensions, const GrD3DTextureInfo& info,
|
||||
sk_sp<GrD3DResourceState> state, GrMipMapsStatus mipMapsStatus,
|
||||
GrBackendObjectOwnership ownership, GrWrapCacheable cacheable,
|
||||
GrIOType ioType)
|
||||
: GrSurface(gpu, dimensions, info.fProtected)
|
||||
, GrD3DSurfaceResource(info, std::move(state), ownership)
|
||||
, INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipMapsStatus) {
|
||||
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (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 GrD3DTextureInfo& info,
|
||||
sk_sp<GrD3DResourceState> state,
|
||||
GrMipMapsStatus mipMapsStatus,
|
||||
GrBackendObjectOwnership ownership)
|
||||
: GrSurface(gpu, dimensions, info.fProtected)
|
||||
, GrD3DSurfaceResource(info, state, ownership)
|
||||
, INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipMapsStatus) {
|
||||
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == info.fLevelCount));
|
||||
}
|
||||
|
||||
sk_sp<GrD3DTexture> GrD3DTexture::MakeNewTexture(GrD3DGpu* gpu, SkBudgeted budgeted,
|
||||
SkISize dimensions,
|
||||
const D3D12_RESOURCE_DESC& desc,
|
||||
GrProtected isProtected,
|
||||
GrMipMapsStatus mipMapsStatus) {
|
||||
GrD3DTextureInfo info;
|
||||
if (!GrD3DSurfaceResource::InitTextureInfo(gpu, desc, isProtected, &info)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrD3DResourceState> state(
|
||||
new GrD3DResourceState(static_cast<D3D12_RESOURCE_STATES>(info.fResourceState)));
|
||||
|
||||
return sk_sp<GrD3DTexture>(new GrD3DTexture(gpu, budgeted, dimensions, info, std::move(state),
|
||||
mipMapsStatus));
|
||||
}
|
||||
|
||||
sk_sp<GrD3DTexture> GrD3DTexture::MakeWrappedTexture(GrD3DGpu* gpu,
|
||||
SkISize dimensions,
|
||||
GrWrapOwnership wrapOwnership,
|
||||
GrWrapCacheable cacheable,
|
||||
GrIOType ioType,
|
||||
const GrD3DTextureInfo& 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));
|
||||
|
||||
GrMipMapsStatus mipMapsStatus = info.fLevelCount > 1 ? GrMipMapsStatus::kValid
|
||||
: GrMipMapsStatus::kNotAllocated;
|
||||
|
||||
GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
|
||||
? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
|
||||
return sk_sp<GrD3DTexture>(new GrD3DTexture(gpu, dimensions, info, std::move(state),
|
||||
mipMapsStatus, ownership, cacheable, ioType));
|
||||
}
|
||||
|
||||
void GrD3DTexture::onRelease() {
|
||||
// We're about to be severed from our GrManagedResource. If there are "finish" idle procs we
|
||||
// have to decide who will handle them. If the resource is still tied to a command buffer we let
|
||||
// it handle them. Otherwise, we handle them.
|
||||
if (this->hasResource() && this->resource()->isQueuedForWorkOnGpu()) {
|
||||
this->removeFinishIdleProcs();
|
||||
}
|
||||
|
||||
this->releaseTexture(this->getD3DGpu());
|
||||
|
||||
INHERITED::onRelease();
|
||||
}
|
||||
|
||||
void GrD3DTexture::onAbandon() {
|
||||
// We're about to be severed from our GrManagedResource. If there are "finish" idle procs we
|
||||
// have to decide who will handle them. If the resource is still tied to a command buffer we let
|
||||
// it handle them. Otherwise, we handle them.
|
||||
if (this->hasResource() && this->resource()->isQueuedForWorkOnGpu()) {
|
||||
this->removeFinishIdleProcs();
|
||||
}
|
||||
|
||||
this->releaseTexture(this->getD3DGpu());
|
||||
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());
|
||||
}
|
||||
|
||||
void GrD3DTexture::addIdleProc(sk_sp<GrRefCntedCallback> idleProc, IdleState type) {
|
||||
INHERITED::addIdleProc(idleProc, type);
|
||||
if (type == IdleState::kFinished) {
|
||||
if (auto* resource = this->resource()) {
|
||||
resource->addIdleProc(this, std::move(idleProc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrD3DTexture::callIdleProcsOnBehalfOfResource() {
|
||||
// If we got here then the resource is being removed from its last command buffer and the
|
||||
// texture is idle in the cache. Any kFlush idle procs should already have been called. So
|
||||
// the texture and resource should have the same set of procs.
|
||||
SkASSERT(this->resource());
|
||||
SkASSERT(this->resource()->idleProcCnt() == fIdleProcs.count());
|
||||
#ifdef SK_DEBUG
|
||||
for (int i = 0; i < fIdleProcs.count(); ++i) {
|
||||
SkASSERT(fIdleProcs[i] == this->resource()->idleProc(i));
|
||||
}
|
||||
#endif
|
||||
fIdleProcs.reset();
|
||||
this->resource()->resetIdleProcs();
|
||||
}
|
||||
|
||||
void GrD3DTexture::willRemoveLastRef() {
|
||||
if (!fIdleProcs.count()) {
|
||||
return;
|
||||
}
|
||||
// This is called when the GrTexture is purgeable. However, we need to check whether the
|
||||
// Resource is still owned by any command buffers. If it is then it will call the proc.
|
||||
auto* resource = this->hasResource() ? this->resource() : nullptr;
|
||||
bool callFinishProcs = !resource || !resource->isQueuedForWorkOnGpu();
|
||||
if (callFinishProcs) {
|
||||
// Everything must go!
|
||||
fIdleProcs.reset();
|
||||
resource->resetIdleProcs();
|
||||
} else {
|
||||
// The procs that should be called on flush but not finish are those that are owned
|
||||
// by the GrD3DTexture and not the Resource. We do this by copying the resource's array
|
||||
// and thereby dropping refs to procs we own but the resource does not.
|
||||
SkASSERT(resource);
|
||||
fIdleProcs.reset(resource->idleProcCnt());
|
||||
for (int i = 0; i < fIdleProcs.count(); ++i) {
|
||||
fIdleProcs[i] = resource->idleProc(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrD3DTexture::removeFinishIdleProcs() {
|
||||
// This should only be called by onRelease/onAbandon when we have already checked for a
|
||||
// resource.
|
||||
const auto* resource = this->resource();
|
||||
SkASSERT(resource);
|
||||
SkSTArray<4, sk_sp<GrRefCntedCallback>> procsToKeep;
|
||||
int resourceIdx = 0;
|
||||
// The idle procs that are common between the GrD3DTexture and its Resource should be found in
|
||||
// the same order.
|
||||
for (int i = 0; i < fIdleProcs.count(); ++i) {
|
||||
if (fIdleProcs[i] == resource->idleProc(resourceIdx)) {
|
||||
++resourceIdx;
|
||||
} else {
|
||||
procsToKeep.push_back(fIdleProcs[i]);
|
||||
}
|
||||
}
|
||||
SkASSERT(resourceIdx == resource->idleProcCnt());
|
||||
fIdleProcs = procsToKeep;
|
||||
}
|
87
src/gpu/d3d/GrD3DTexture.h
Normal file
87
src/gpu/d3d/GrD3DTexture.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrD3DTexture_DEFINED
|
||||
#define GrD3DTexture_DEFINED
|
||||
|
||||
#include "src/core/SkLRUCache.h"
|
||||
#include "src/gpu/GrSamplerState.h"
|
||||
#include "src/gpu/GrTexture.h"
|
||||
#include "src/gpu/d3d/GrD3DSurfaceResource.h"
|
||||
|
||||
class GrD3DTexture : public GrTexture, public virtual GrD3DSurfaceResource {
|
||||
public:
|
||||
static sk_sp<GrD3DTexture> MakeNewTexture(GrD3DGpu*,
|
||||
SkBudgeted,
|
||||
SkISize dimensions,
|
||||
const D3D12_RESOURCE_DESC&,
|
||||
GrProtected,
|
||||
GrMipMapsStatus);
|
||||
|
||||
static sk_sp<GrD3DTexture> MakeWrappedTexture(GrD3DGpu*,
|
||||
SkISize dimensions,
|
||||
GrWrapOwnership,
|
||||
GrWrapCacheable,
|
||||
GrIOType,
|
||||
const GrD3DTextureInfo&,
|
||||
sk_sp<GrD3DResourceState>);
|
||||
|
||||
~GrD3DTexture() override {}
|
||||
|
||||
GrBackendTexture getBackendTexture() const override;
|
||||
|
||||
GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
|
||||
|
||||
void textureParamsModified() override {}
|
||||
|
||||
void addIdleProc(sk_sp<GrRefCntedCallback>, IdleState) override;
|
||||
void callIdleProcsOnBehalfOfResource() override;
|
||||
|
||||
protected:
|
||||
GrD3DTexture(GrD3DGpu*,
|
||||
SkISize dimensions,
|
||||
const GrD3DTextureInfo&,
|
||||
sk_sp<GrD3DResourceState>,
|
||||
GrMipMapsStatus,
|
||||
GrBackendObjectOwnership);
|
||||
|
||||
GrD3DGpu* getD3DGpu() const;
|
||||
|
||||
void onAbandon() override;
|
||||
void onRelease() override;
|
||||
|
||||
bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void willRemoveLastRef() override;
|
||||
|
||||
private:
|
||||
GrD3DTexture(GrD3DGpu*, SkBudgeted, SkISize dimensions, const GrD3DTextureInfo&,
|
||||
sk_sp<GrD3DResourceState>, GrMipMapsStatus);
|
||||
GrD3DTexture(GrD3DGpu*, SkISize dimensions, const GrD3DTextureInfo&, sk_sp<GrD3DResourceState>,
|
||||
GrMipMapsStatus, GrBackendObjectOwnership, GrWrapCacheable, GrIOType);
|
||||
|
||||
// In D3D we call the release proc after we are finished with the underlying
|
||||
// GrSurfaceResource::Resource object (which occurs after the GPU has finished all work on it).
|
||||
void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override {
|
||||
// Forward the release proc on to GrSurfaceResource
|
||||
this->setResourceRelease(std::move(releaseHelper));
|
||||
}
|
||||
|
||||
void removeFinishIdleProcs();
|
||||
|
||||
struct SamplerHash {
|
||||
uint32_t operator()(GrSamplerState state) const {
|
||||
return GrSamplerState::GenerateKey(state);
|
||||
}
|
||||
};
|
||||
|
||||
typedef GrTexture INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user