More fixes to get D3D tests running.
* Set up D3D backend texture creation
* Fix GrD3DBackendSurfaceInfo initialization
* Minor fix to get wrapped RTs into the cache
Bug: skia:9935
Change-Id: Ic5319a7d059c4d969894529a326a91de0192f9eb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282679
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp
index b8b85fe..3e3951a 100644
--- a/src/gpu/d3d/GrD3DGpu.cpp
+++ b/src/gpu/d3d/GrD3DGpu.cpp
@@ -7,7 +7,9 @@
#include "src/gpu/d3d/GrD3DGpu.h"
+#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/d3d/GrD3DBackendContext.h"
+#include "src/core/SkMipMap.h"
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DCaps.h"
#include "src/gpu/d3d/GrD3DOpsRenderPass.h"
@@ -183,7 +185,7 @@
resourceDesc.SampleDesc.Count = 1;
resourceDesc.SampleDesc.Quality = 0; // quality levels are only supported for tiled resources
// so ignore for now
- resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // use driver-selected swizzle for now
+ resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // use driver-selected swizzle
resourceDesc.Flags = usageFlags;
GrMipMapsStatus mipMapsStatus =
@@ -420,27 +422,140 @@
return nullptr;
}
+bool GrD3DGpu::createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,
+ SkISize dimensions,
+ GrTexturable texturable,
+ GrRenderable renderable,
+ GrMipMapped mipMapped,
+ GrD3DTextureResourceInfo* info,
+ GrProtected isProtected,
+ const BackendTextureData* data) {
+ SkASSERT(texturable == GrTexturable::kYes || renderable == GrRenderable::kYes);
+ if (texturable == GrTexturable::kNo) {
+ SkASSERT(!data && mipMapped == GrMipMapped::kNo);
+ }
+
+ if (this->protectedContext() != (isProtected == GrProtected::kYes)) {
+ return false;
+ }
+
+ if (texturable == GrTexturable::kYes && !this->d3dCaps().isFormatTexturable(dxgiFormat)) {
+ return false;
+ }
+
+ if (renderable == GrRenderable::kYes && !this->d3dCaps().isFormatRenderable(dxgiFormat, 1)) {
+ return false;
+ }
+
+ int numMipLevels = 1;
+ if (mipMapped == GrMipMapped::kYes) {
+ numMipLevels = SkMipMap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
+ }
+
+ // create the texture
+ D3D12_RESOURCE_FLAGS usageFlags = D3D12_RESOURCE_FLAG_NONE;
+ if (renderable == GrRenderable::kYes) {
+ usageFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+ }
+
+ D3D12_RESOURCE_DESC resourceDesc;
+ resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ resourceDesc.Alignment = 0; // use default alignment
+ resourceDesc.Width = dimensions.fWidth;
+ resourceDesc.Height = dimensions.fHeight;
+ resourceDesc.DepthOrArraySize = 1;
+ resourceDesc.MipLevels = numMipLevels;
+ resourceDesc.Format = dxgiFormat;
+ resourceDesc.SampleDesc.Count = 1;
+ resourceDesc.SampleDesc.Quality = 0; // quality levels are only supported for tiled resources
+ // so ignore for now
+ resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // use driver-selected swizzle
+ resourceDesc.Flags = usageFlags;
+
+ if (!GrD3DTextureResource::InitTextureResourceInfo(this, resourceDesc, isProtected, info)) {
+ SkDebugf("Failed to init texture resource info\n");
+ return false;
+ }
+
+ if (!data) {
+ return true;
+ }
+
+ // TODO: upload the data
+
+ return true;
+}
+
GrBackendTexture GrD3DGpu::onCreateBackendTexture(SkISize dimensions,
const GrBackendFormat& format,
- GrRenderable,
+ GrRenderable renderable,
GrMipMapped mipMapped,
- GrProtected,
- const BackendTextureData*) {
- // TODO
- return GrBackendTexture();
+ GrProtected isProtected,
+ const BackendTextureData* data) {
+ this->handleDirtyContext();
+
+ const GrD3DCaps& caps = this->d3dCaps();
+
+ if (this->protectedContext() != (isProtected == GrProtected::kYes)) {
+ return {};
+ }
+
+ DXGI_FORMAT dxgiFormat;
+ if (!format.asDxgiFormat(&dxgiFormat)) {
+ return {};
+ }
+
+ // TODO: move the texturability check up to GrGpu::createBackendTexture and just assert here
+ if (!caps.isFormatTexturable(dxgiFormat)) {
+ return {};
+ }
+
+ GrD3DTextureResourceInfo info;
+ if (!this->createTextureResourceForBackendSurface(dxgiFormat, dimensions, GrTexturable::kYes,
+ renderable, mipMapped,
+ &info, isProtected, data)) {
+ return {};
+ }
+
+ return GrBackendTexture(dimensions.width(), dimensions.height(), info);
}
GrBackendTexture GrD3DGpu::onCreateCompressedBackendTexture(SkISize dimensions,
const GrBackendFormat& format,
GrMipMapped mipMapped,
- GrProtected,
- const BackendTextureData*) {
- // TODO
- return GrBackendTexture();
+ GrProtected isProtected,
+ const BackendTextureData* data) {
+ this->handleDirtyContext();
+
+ const GrD3DCaps& caps = this->d3dCaps();
+
+ if (this->protectedContext() != (isProtected == GrProtected::kYes)) {
+ return {};
+ }
+
+ DXGI_FORMAT dxgiFormat;
+ if (!format.asDxgiFormat(&dxgiFormat)) {
+ return {};
+ }
+
+ // TODO: move the texturability check up to GrGpu::createBackendTexture and just assert here
+ if (!caps.isFormatTexturable(dxgiFormat)) {
+ return {};
+ }
+
+ GrD3DTextureResourceInfo info;
+ if (!this->createTextureResourceForBackendSurface(dxgiFormat, dimensions, GrTexturable::kYes,
+ GrRenderable::kNo, mipMapped,
+ &info, isProtected, data)) {
+ return {};
+ }
+
+ return GrBackendTexture(dimensions.width(), dimensions.height(), info);
}
void GrD3DGpu::deleteBackendTexture(const GrBackendTexture& tex) {
- // TODO
+ SkASSERT(GrBackendApi::kDirect3D == tex.fBackend);
+ // Nothing to do here, will get cleaned up when the GrBackendTexture object goes away
}
bool GrD3DGpu::compile(const GrProgramDesc&, const GrProgramInfo&) {
@@ -449,15 +564,51 @@
#if GR_TEST_UTILS
bool GrD3DGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
- // TODO
- return false;
+ SkASSERT(GrBackendApi::kDirect3D == tex.backend());
+
+ GrD3DTextureResourceInfo info;
+ if (!tex.getD3DTextureResourceInfo(&info)) {
+ return false;
+ }
+ ID3D12Resource* textureResource = info.fResource.get();
+ if (!textureResource) {
+ return false;
+ }
+ return !(textureResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE);
}
GrBackendRenderTarget GrD3DGpu::createTestingOnlyBackendRenderTarget(int w, int h,
GrColorType colorType) {
- // TODO
- return GrBackendRenderTarget();
+ this->handleDirtyContext();
+
+ if (w > this->caps()->maxRenderTargetSize() || h > this->caps()->maxRenderTargetSize()) {
+ return GrBackendRenderTarget();
+ }
+
+ DXGI_FORMAT dxgiFormat = this->d3dCaps().getFormatFromColorType(colorType);
+
+ GrD3DTextureResourceInfo info;
+ if (!this->createTextureResourceForBackendSurface(dxgiFormat, { w, h }, GrTexturable::kNo,
+ GrRenderable::kYes, GrMipMapped::kNo,
+ &info, GrProtected::kNo, nullptr)) {
+ return {};
+ }
+
+ return GrBackendRenderTarget(w, h, 1, info);
}
-void GrD3DGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {}
+void GrD3DGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& rt) {
+ SkASSERT(GrBackendApi::kDirect3D == rt.backend());
+
+ GrD3DTextureResourceInfo info;
+ if (rt.getD3DTextureResourceInfo(&info)) {
+ this->testingOnly_flushGpuAndSync();
+ // Nothing else to do here, will get cleaned up when the GrBackendRenderTarget
+ // is deleted.
+ }
+}
+
+void GrD3DGpu::testingOnly_flushGpuAndSync() {
+ // TODO
+}
#endif
diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h
index 1d8e016..a8bb98b 100644
--- a/src/gpu/d3d/GrD3DGpu.h
+++ b/src/gpu/d3d/GrD3DGpu.h
@@ -49,7 +49,7 @@
GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
- void testingOnly_flushGpuAndSync() override {}
+ void testingOnly_flushGpuAndSync() override;
#endif
GrStencilAttachment* createStencilAttachmentForRenderTarget(
@@ -184,6 +184,15 @@
void checkForFinishedCommandLists();
+ bool createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,
+ SkISize dimensions,
+ GrTexturable texturable,
+ GrRenderable renderable,
+ GrMipMapped mipMapped,
+ GrD3DTextureResourceInfo* info,
+ GrProtected isProtected,
+ const BackendTextureData* data);
+
gr_cp<ID3D12Device> fDevice;
gr_cp<ID3D12CommandQueue> fQueue;
diff --git a/src/gpu/d3d/GrD3DRenderTarget.cpp b/src/gpu/d3d/GrD3DRenderTarget.cpp
index c70ddfe..793c4b1 100644
--- a/src/gpu/d3d/GrD3DRenderTarget.cpp
+++ b/src/gpu/d3d/GrD3DRenderTarget.cpp
@@ -113,9 +113,9 @@
static_cast<D3D12_RESOURCE_STATES>(msInfo.fResourceState)));
d3dRT = new GrD3DRenderTarget(gpu, dimensions, sampleCnt, info, std::move(state), msInfo,
- std::move(msState));
+ std::move(msState), kWrapped);
} else {
- d3dRT = new GrD3DRenderTarget(gpu, dimensions, info, std::move(state));
+ d3dRT = new GrD3DRenderTarget(gpu, dimensions, info, std::move(state), kWrapped);
}
return sk_sp<GrD3DRenderTarget>(d3dRT);
diff --git a/src/gpu/d3d/GrD3DRenderTarget.h b/src/gpu/d3d/GrD3DRenderTarget.h
index 8e69adb..220e944 100644
--- a/src/gpu/d3d/GrD3DRenderTarget.h
+++ b/src/gpu/d3d/GrD3DRenderTarget.h
@@ -39,7 +39,7 @@
GrD3DTextureResource* msaaTextureResource() { return fMSAATextureResource.get(); }
bool canAttemptStencilAttachment() const override {
- return false; // For now
+ return true;
}
GrBackendRenderTarget getBackendRenderTarget() const override;
diff --git a/src/gpu/d3d/GrD3DTypesPriv.cpp b/src/gpu/d3d/GrD3DTypesPriv.cpp
index b50c503..a84ea7e 100644
--- a/src/gpu/d3d/GrD3DTypesPriv.cpp
+++ b/src/gpu/d3d/GrD3DTypesPriv.cpp
@@ -18,13 +18,17 @@
void GrD3DBackendSurfaceInfo::cleanup() {
SkSafeUnref(fResourceState);
fResourceState = nullptr;
+ delete fTextureResourceInfo;
+ fTextureResourceInfo = nullptr;
};
void GrD3DBackendSurfaceInfo::assign(const GrD3DBackendSurfaceInfo& that, bool isThisValid) {
- fTextureResourceInfo.reset(new GrD3DTextureResourceInfo(*that.fTextureResourceInfo));
+ GrD3DTextureResourceInfo* oldInfo = fTextureResourceInfo;
GrD3DResourceState* oldLayout = fResourceState;
+ fTextureResourceInfo = new GrD3DTextureResourceInfo(*that.fTextureResourceInfo);
fResourceState = SkSafeRef(that.fResourceState);
if (isThisValid) {
+ delete oldInfo;
SkSafeUnref(oldLayout);
}
}
@@ -44,6 +48,7 @@
}
bool GrD3DBackendSurfaceInfo::isProtected() const {
+ SkASSERT(fTextureResourceInfo);
return fTextureResourceInfo->fProtected == GrProtected::kYes;
}