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/GrD3DGpu.h",
|
||||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.cpp",
|
"$_src/gpu/d3d/GrD3DOpsRenderPass.cpp",
|
||||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.h",
|
"$_src/gpu/d3d/GrD3DOpsRenderPass.h",
|
||||||
"$_src/gpu/d3d/GrD3DResource.cpp",
|
|
||||||
"$_src/gpu/d3d/GrD3DResource.h",
|
|
||||||
"$_src/gpu/d3d/GrD3DResourceProvider.cpp",
|
"$_src/gpu/d3d/GrD3DResourceProvider.cpp",
|
||||||
"$_src/gpu/d3d/GrD3DResourceProvider.h",
|
"$_src/gpu/d3d/GrD3DResourceProvider.h",
|
||||||
"$_src/gpu/d3d/GrD3DResourceState.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/GrD3DTypesPriv.cpp",
|
||||||
"$_src/gpu/d3d/GrD3DUtil.cpp",
|
"$_src/gpu/d3d/GrD3DUtil.cpp",
|
||||||
"$_src/gpu/d3d/GrD3DUtil.h",
|
"$_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