35#if defined(GR_TEST_UTILS)
36#include <DXProgrammableCapture.h>
60 SkDEBUGFAIL(
"No supplied Direct3D memory allocator and unable to create one internally.");
64 return std::unique_ptr<GrGpu>(
new GrD3DGpu(direct,
83 , fDevice(backendContext.fDevice)
84 , fQueue(backendContext.fQueue)
85 , fMemoryAllocator(
std::move(allocator))
86 , fResourceProvider(this)
87 , fStagingBufferManager(this)
90 this->initCaps(sk_make_sp<GrD3DCaps>(contextOptions,
94 fCurrentDirectCommandList = fResourceProvider.findOrCreateDirectCommandList();
99 IID_PPV_ARGS(&fFence)));
101#if defined(GR_TEST_UTILS)
102 HRESULT getAnalysis = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&fGraphicsAnalysis));
103 if (
FAILED(getAnalysis)) {
104 fGraphicsAnalysis =
nullptr;
110 this->destroyResources();
113void GrD3DGpu::destroyResources() {
114 if (fCurrentDirectCommandList) {
115 fCurrentDirectCommandList->close();
116 fCurrentDirectCommandList->reset();
120 this->waitForQueueCompletion();
122 SkDEBUGCODE(uint64_t fenceValue = fFence->GetCompletedValue();)
126 while (!fOutstandingCommandLists.
empty()) {
127 OutstandingCommandList* list = (OutstandingCommandList*)fOutstandingCommandLists.
front();
128 SkASSERT(list->fFenceValue <= fenceValue);
130 list->~OutstandingCommandList();
134 fStagingBufferManager.
reset();
149 if (!fCachedOpsRenderPass) {
153 if (!fCachedOpsRenderPass->set(rt, origin, bounds, colorInfo, stencilInfo, sampledProxies)) {
156 return fCachedOpsRenderPass.get();
159bool GrD3DGpu::submitDirectCommandList(SyncQueue sync) {
160 SkASSERT(fCurrentDirectCommandList);
163 for (
int i = 0; i < fMipmapCPUDescriptors.
size(); ++i) {
166 fMipmapCPUDescriptors.
clear();
173 if (sync == SyncQueue::kForce) {
174 this->waitForQueueCompletion();
175 this->checkForFinishedCommandLists();
185 new (fOutstandingCommandLists.
push_back()) OutstandingCommandList(
186 std::move(fCurrentDirectCommandList), fCurrentFenceValue);
188 if (sync == SyncQueue::kForce) {
189 this->waitForQueueCompletion();
197 this->checkForFinishedCommandLists();
199 SkASSERT(fCurrentDirectCommandList);
203void GrD3DGpu::checkForFinishedCommandLists() {
204 uint64_t currentFenceValue = fFence->GetCompletedValue();
211 OutstandingCommandList* front = (OutstandingCommandList*)fOutstandingCommandLists.
front();
212 while (front && front->fFenceValue <= currentFenceValue) {
213 std::unique_ptr<GrD3DDirectCommandList> currList(std::move(front->fCommandList));
215 front->~OutstandingCommandList();
218 front = (OutstandingCommandList*)fOutstandingCommandLists.
front();
222void GrD3DGpu::waitForQueueCompletion() {
223 if (fFence->GetCompletedValue() < fCurrentFenceValue) {
228 WaitForSingleObject(fenceEvent, INFINITE);
229 CloseHandle(fenceEvent);
234 SkASSERT(fCachedOpsRenderPass.get() == renderPass);
236 fCachedOpsRenderPass->submit();
237 fCachedOpsRenderPass.reset();
259 OutstandingCommandList* back = (OutstandingCommandList*)fOutstandingCommandLists.
back();
261 back->fCommandList->addFinishedCallback(finishedCallback);
263 fCurrentDirectCommandList->addFinishedCallback(std::move(finishedCallback));
267 DXGI_FORMAT dxgiFormat,
269 int renderTargetSampleCnt,
274 std::string_view label) {
275 D3D12_RESOURCE_FLAGS usageFlags = D3D12_RESOURCE_FLAG_NONE;
276 if (renderable == GrRenderable::kYes) {
277 usageFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
284 D3D12_RESOURCE_DESC resourceDesc = {};
285 resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
288 resourceDesc.Alignment = 0;
289 resourceDesc.Width = dimensions.
fWidth;
290 resourceDesc.Height = dimensions.
fHeight;
291 resourceDesc.DepthOrArraySize = 1;
292 resourceDesc.MipLevels = mipLevelCount;
293 resourceDesc.Format = dxgiFormat;
294 resourceDesc.SampleDesc.Count = 1;
295 resourceDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
296 resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
297 resourceDesc.Flags = usageFlags;
299 if (renderable == GrRenderable::kYes) {
301 this, budgeted, dimensions, renderTargetSampleCnt, resourceDesc, isProtected,
302 mipmapStatus, label);
305 mipmapStatus, label);
312 int renderTargetSampleCnt,
316 uint32_t levelClearMask,
317 std::string_view label) {
318 DXGI_FORMAT dxgiFormat;
326 renderTargetSampleCnt, budgeted, isProtected,
327 mipLevelCount, mipmapStatus, label);
332 if (levelClearMask) {
336 return std::move(tex);
340 D3D12_PLACED_SUBRESOURCE_FOOTPRINT* placedFootprints,
341 UINT* numRows, UINT64* rowSizeInBytes,
342 const void* compressedData,
int numMipLevels) {
343 SkASSERT(compressedData && numMipLevels);
347 const char* src =
static_cast<const char*
>(compressedData);
348 for (
int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
350 char* dst = mapPtr + placedFootprints[currentMipLevel].Offset;
351 SkRectMemcpy(dst, placedFootprints[currentMipLevel].Footprint.RowPitch,
352 src, rowSizeInBytes[currentMipLevel], rowSizeInBytes[currentMipLevel],
353 numRows[currentMipLevel]);
354 src += numRows[currentMipLevel] * rowSizeInBytes[currentMipLevel];
365 DXGI_FORMAT dxgiFormat;
371 compression, dimensions, mipmapped == skgpu::Mipmapped::kYes));
373 int mipLevelCount = 1;
374 if (mipmapped == skgpu::Mipmapped::kYes) {
389 "D3DGpu_CreateCompressedTexture");
394 ID3D12Resource* d3dResource = d3dTex->d3dResource();
396 D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
398 SkASSERT(1 == mipLevelCount || mipLevelCount == (
int)desc.MipLevels);
403 UINT64 combinedBufferSize;
406 desc.Width = dimensions.
width();
407 desc.Height = dimensions.
height();
408 fDevice->GetCopyableFootprints(&desc, 0, mipLevelCount, 0, placedFootprints.
get(),
409 numRows.
get(), rowSizeInBytes.
get(), &combinedBufferSize);
413 combinedBufferSize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
421 rowSizeInBytes.
get(), data, mipLevelCount);
424 for (
int i = 0; i < mipLevelCount; ++i) {
425 placedFootprints[i].Offset += slice.
fOffset;
429 fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer, d3dTex.
get(), mipLevelCount,
430 placedFootprints.
get(), 0, 0);
432 return std::move(d3dTex);
437 return rt->numSamples();
445 if (srcRect.
size() != dstRect.
size()) {
448 if (src->isProtected() && !dst->isProtected()) {
449 SkDebugf(
"Can't copy from protected memory to non-protected");
464 dstTexResource =
static_cast<GrD3DTexture*
>(dst->asTexture());
472 srcTexResource =
static_cast<GrD3DTexture*
>(src->asTexture());
475 DXGI_FORMAT dstFormat = dstTexResource->
dxgiFormat();
476 DXGI_FORMAT srcFormat = srcTexResource->
dxgiFormat();
480 this->copySurfaceAsResolve(dst, src, srcRect, dstPoint);
484 if (this->
d3dCaps().canCopyTexture(dstFormat, dstSampleCnt, srcFormat, srcSampleCnt)) {
485 this->copySurfaceAsCopyTexture(dst, src, dstTexResource, srcTexResource, srcRect, dstPoint);
499 DXGI_FORMAT dstFormat = dstResource->
dxgiFormat();
500 DXGI_FORMAT srcFormat;
502 SkASSERT(this->
d3dCaps().canCopyTexture(dstFormat, dstSampleCnt, srcFormat, srcSampleCnt));
504 if (src->isProtected() && !dst->isProtected()) {
505 SkDebugf(
"Can't copy from protected memory to non-protected");
512 D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
513 dstLocation.pResource = dstResource->
d3dResource();
514 dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
515 dstLocation.SubresourceIndex = 0;
517 D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
518 srcLocation.pResource = srcResource->
d3dResource();
519 srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
520 srcLocation.SubresourceIndex = 0;
522 D3D12_BOX srcBox = {};
523 srcBox.left = srcRect.
fLeft;
524 srcBox.top = srcRect.
fTop;
525 srcBox.right = srcRect.
fRight;
526 srcBox.bottom = srcRect.
fBottom;
530 fCurrentDirectCommandList->copyTextureRegionToTexture(dstResource->
resource(),
532 dstPoint.
fX, dstPoint.
fY,
548 this->resolveTexture(dst, dstPoint.
fX, dstPoint.
fY, srcRT, srcRect);
555void GrD3DGpu::resolveTexture(
GrSurface* dst, int32_t dstX, int32_t dstY,
558 SkASSERT(src &&
src->numSamples() > 1 &&
src->msaaTextureResource());
571 dstTextureResource->
setResourceState(
this, D3D12_RESOURCE_STATE_RESOLVE_DEST);
572 src->msaaTextureResource()->setResourceState(
this, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
574 fCurrentDirectCommandList->resolveSubresourceRegion(dstTextureResource, dstX, dstY,
575 src->msaaTextureResource(), &srcRect);
583 this->resolveTexture(
target, resolveRect.
fLeft, resolveRect.
fTop, rt, resolveRect);
594 if (surfaceColorType != dstColorType) {
610 D3D12_RESOURCE_DESC desc = texResource->
d3dResource()->GetDesc();
611 D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedFootprint;
612 UINT64 transferTotalBytes;
613 fDevice->GetCopyableFootprints(&desc, 0, 1, 0, &placedFootprint,
614 nullptr,
nullptr, &transferTotalBytes);
623 if (!transferBuffer) {
627 this->readOrTransferPixels(texResource, rect, transferBuffer, placedFootprint);
628 this->submitDirectCommandList(SyncQueue::kForce);
635 size_t tightRowBytes = bpp * rect.width();
637 const void* mappedMemory = transferBuffer->map();
645 placedFootprint.Footprint.RowPitch,
649 transferBuffer->unmap();
657 const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& placedFootprint) {
659 D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
660 srcLocation.pResource = texResource->
d3dResource();
662 srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
663 srcLocation.SubresourceIndex = 0;
665 D3D12_BOX srcBox = {};
666 srcBox.left =
rect.left();
667 srcBox.top =
rect.top();
668 srcBox.right =
rect.right();
669 srcBox.bottom =
rect.bottom();
674 D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
675 dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
676 dstLocation.PlacedFootprint = placedFootprint;
683 fCurrentDirectCommandList->copyTextureRegionToBuffer(transferBuffer, &dstLocation, 0, 0,
684 texResource->
resource(), &srcLocation,
694 bool prepForTexSampling) {
701 if (!mipLevelCount || !texels[0].fPixels) {
706 bool success =
false;
711 SkASSERT(mipLevelCount <= d3dTex->maxMipmapLevel() + 1);
712 success = this->uploadToTexture(d3dTex, rect, srcColorType, texels, mipLevelCount);
714 if (prepForTexSampling) {
734 if (rect.isEmpty()) {
743 D3D12_RESOURCE_DESC
desc = d3dResource->GetDesc();
745 SkASSERT(1 == mipLevelCount || mipLevelCount == (
int)
desc.MipLevels);
747 if (1 == mipLevelCount && !texels[0].fPixels) {
751 for (
int i = 0; i < mipLevelCount; ++i) {
753 if (!texels[i].fPixels) {
759 UINT64 combinedBufferSize;
764 fDevice->GetCopyableFootprints(&desc, 0, mipLevelCount, 0, placedFootprints.get(),
765 nullptr,
nullptr, &combinedBufferSize);
770 combinedBufferSize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
777 int currentWidth =
rect.width();
778 int currentHeight =
rect.height();
779 for (
int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
780 if (texels[currentMipLevel].fPixels) {
782 const size_t trimRowBytes = currentWidth * bpp;
783 const size_t srcRowBytes = texels[currentMipLevel].
fRowBytes;
785 char*
dst = bufferData + placedFootprints[currentMipLevel].Offset;
788 const char*
src = (
const char*)texels[currentMipLevel].fPixels;
789 SkRectMemcpy(dst, placedFootprints[currentMipLevel].Footprint.RowPitch,
790 src, srcRowBytes, trimRowBytes, currentHeight);
792 currentWidth = std::max(1, currentWidth / 2);
793 currentHeight = std::max(1, currentHeight / 2);
797 for (
int i = 0; i < mipLevelCount; ++i) {
798 placedFootprints[i].Offset += slice.
fOffset;
802 fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer,
805 placedFootprints.get(),
809 if (mipLevelCount < (
int)
desc.MipLevels) {
828 fCurrentDirectCommandList->copyBufferToBuffer(std::move(d3dDst),
830 d3dSrc->d3dResource(),
851 if (!transferBuffer) {
861 if (
SkToBool(bufferOffset & (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1))) {
880 D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedFootprint = {};
881 ID3D12Resource* d3dResource = d3dTex->
d3dResource();
883 D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
884 desc.Width = rect.width();
885 desc.Height = rect.height();
887 fDevice->GetCopyableFootprints(&desc, 0, 1, 0, &placedFootprint,
888 nullptr,
nullptr, &totalBytes);
889 placedFootprint.Offset = bufferOffset;
895 ID3D12Resource* d3dBuffer =
static_cast<GrD3DBuffer*
>(transferBuffer.
get())->d3dResource();
896 fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer,
925 if (
SkToBool(
offset & (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT-1))) {
944 D3D12_RESOURCE_DESC desc = texResource->
d3dResource()->GetDesc();
945 desc.Width = rect.width();
946 desc.Height = rect.height();
947 D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedFootprint;
948 UINT64 transferTotalBytes;
949 fDevice->GetCopyableFootprints(&desc, 0, 1,
offset, &placedFootprint,
950 nullptr,
nullptr, &transferTotalBytes);
953 this->readOrTransferPixels(texResource, rect, transferBuffer, placedFootprint);
962 if (!
info.fResource.get()) {
973 if (
info.fSampleCount != 1) {
992 if (!tex.getD3DTextureResourceInfo(&textureInfo)) {
1026 if (!tex.getD3DTextureResourceInfo(&textureInfo)) {
1052 sampleCnt, cacheable,
1053 textureInfo, std::move(
state));
1058 if (!rt.getD3DTextureResourceInfo(&
info)) {
1083 SkASSERT(tgt->canAttemptStencilAttachment(tgt->numSamples() > 1));
1086 return std::move(tgt);
1101 return (
format == DXGI_FORMAT_B8G8R8A8_UNORM);
1119 DXGI_FORMAT originalFormat = d3dTex->dxgiFormat();
1120 D3D12_RESOURCE_DESC originalDesc = d3dTex->d3dResource()->GetDesc();
1122 if (
caps.isFormatUnorderedAccessible(originalFormat) &&
1123 (originalDesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)) {
1127 D3D12_RESOURCE_DESC uavDesc = originalDesc;
1128 uavDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
1130 if (!
caps.isFormatUnorderedAccessible(originalFormat)) {
1132 if (
is_bgra(originalFormat)) {
1133 uavDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1138 if (
caps.standardSwizzleLayoutSupport()) {
1139 uavDesc.Layout = D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE;
1156 "RegenerateMipMapLevels");
1161 d3dTex->setResourceState(
this, D3D12_RESOURCE_STATE_COPY_SOURCE);
1162 if (!
caps.isFormatUnorderedAccessible(originalFormat) &&
is_bgra(originalFormat)) {
1165 D3D12_RESOURCE_STATE_COPY_DEST);
1169 bgraAliasTexture->resource(),
1170 bgraAliasTexture->d3dResource());
1175 bgraAliasTexture->d3dResource(),
1176 uavTexture->resource(),
1177 uavTexture->d3dResource());
1180 uavTexture->setResourceState(
this, D3D12_RESOURCE_STATE_COPY_DEST);
1185 uint32_t levelCount = d3dTex->mipLevels();
1201 std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> samplers(1);
1207 D3D12_RESOURCE_STATES currentResourceState = uavTexture->currentState();
1208 D3D12_RESOURCE_TRANSITION_BARRIER barrier;
1209 barrier.pResource = uavTexture->d3dResource();
1210 barrier.Subresource = 0;
1211 barrier.StateBefore = currentResourceState;
1212 barrier.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1216 for (
unsigned int dstMip = 1; dstMip < levelCount; ++dstMip) {
1217 unsigned int srcMip = dstMip - 1;
1221 unsigned int sampleMode = 0;
1234 uint32_t sampleMode;
1235 } constantData = { {1.f /
width, 1.f /
height}, srcMip, sampleMode };
1237 D3D12_GPU_VIRTUAL_ADDRESS constantsAddress =
1243 std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> shaderViews;
1247 shaderViews.push_back(srvHandle.
fHandle);
1248 fMipmapCPUDescriptors.
push_back(srvHandle);
1252 shaderViews.push_back(uavHandle.
fHandle);
1253 fMipmapCPUDescriptors.
push_back(uavHandle);
1263 srvTable->baseGpuDescriptor());
1266 samplerTable->baseGpuDescriptor());
1269 barrier.Subresource = dstMip;
1270 barrier.StateBefore = currentResourceState;
1271 barrier.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1281 barrier.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1282 barrier.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1287 if (uavTexture.
get() != d3dTex) {
1288 d3dTex->setResourceState(
this, D3D12_RESOURCE_STATE_COPY_DEST);
1289 if (bgraAliasTexture) {
1292 uavTexture->d3dResource(),
1293 bgraAliasTexture->resource(),
1294 bgraAliasTexture->d3dResource());
1296 bgraAliasTexture->setResourceState(
this, D3D12_RESOURCE_STATE_COPY_SOURCE);
1299 barrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
1300 barrier.StateBefore = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1301 barrier.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
1309 barrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
1310 barrier.StateBefore = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1311 barrier.StateAfter = currentResourceState;
1325 SkISize dimensions,
int numStencilSamples) {
1332bool GrD3DGpu::createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,
1350 if (renderable == GrRenderable::kYes && !this->
d3dCaps().isFormatRenderable(dxgiFormat, 1)) {
1354 int numMipLevels = 1;
1355 if (mipmapped == skgpu::Mipmapped::kYes) {
1360 D3D12_RESOURCE_FLAGS usageFlags = D3D12_RESOURCE_FLAG_NONE;
1361 if (renderable == GrRenderable::kYes) {
1362 usageFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
1365 D3D12_RESOURCE_DESC resourceDesc = {};
1366 resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
1367 resourceDesc.Alignment = 0;
1368 resourceDesc.Width = dimensions.
fWidth;
1369 resourceDesc.Height = dimensions.
fHeight;
1370 resourceDesc.DepthOrArraySize = 1;
1371 resourceDesc.MipLevels = numMipLevels;
1372 resourceDesc.Format = dxgiFormat;
1373 resourceDesc.SampleDesc.Count = sampleCnt;
1374 resourceDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
1375 resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
1376 resourceDesc.Flags = usageFlags;
1378 D3D12_CLEAR_VALUE* clearValuePtr =
nullptr;
1379 D3D12_CLEAR_VALUE clearValue = {};
1380 if (renderable == GrRenderable::kYes) {
1381 clearValue.Format = dxgiFormat;
1383 clearValue.Color[0] = 0;
1384 clearValue.Color[1] = 0;
1385 clearValue.Color[2] = 0;
1386 clearValue.Color[3] = 0;
1387 clearValuePtr = &clearValue;
1390 D3D12_RESOURCE_STATES initialState = (renderable == GrRenderable::kYes)
1391 ? D3D12_RESOURCE_STATE_RENDER_TARGET
1392 : D3D12_RESOURCE_STATE_COPY_DEST;
1394 isProtected, clearValuePtr,
info)) {
1395 SkDebugf(
"Failed to init texture resource info\n");
1407 std::string_view label) {
1414 DXGI_FORMAT dxgiFormat;
1415 if (!
format.asDxgiFormat(&dxgiFormat)) {
1425 if (!this->createTextureResourceForBackendSurface(dxgiFormat, dimensions,
GrTexturable::kYes,
1426 renderable, mipmapped, 1, &
info,
1436 DXGI_FORMAT dxgiFormat,
1438 D3D12_PLACED_SUBRESOURCE_FOOTPRINT* placedFootprints,
1439 std::array<float, 4>
color) {
1454 std::array<float, 4>
color) {
1474 texture->setResourceState(
this, D3D12_RESOURCE_STATE_COPY_DEST);
1476 ID3D12Resource* d3dResource =
texture->d3dResource();
1478 D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
1479 unsigned int mipLevelCount = 1;
1480 if (backendTexture.fMipmapped == skgpu::Mipmapped::kYes) {
1486 UINT64 rowSizeInBytes;
1487 UINT64 combinedBufferSize;
1489 fDevice->GetCopyableFootprints(&desc,
1493 placedFootprints.
get(),
1496 &combinedBufferSize);
1500 combinedBufferSize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
1516 placedFootprints[0].Offset += slice.
fOffset;
1518 UINT w = placedFootprints[0].Footprint.Width;
1519 UINT h = placedFootprints[0].Footprint.Height;
1520 for (
unsigned int i = 1; i < mipLevelCount; ++i) {
1521 w = std::max(1U,
w/2);
1522 h = std::max(1U,
h/2);
1523 placedFootprints[i].Offset = placedFootprints[0].Offset;
1524 placedFootprints[i].Footprint.Format = placedFootprints[0].Footprint.Format;
1525 placedFootprints[i].Footprint.Width =
w;
1526 placedFootprints[i].Footprint.Height =
h;
1527 placedFootprints[i].Footprint.Depth = 1;
1528 placedFootprints[i].Footprint.RowPitch = placedFootprints[0].Footprint.RowPitch;
1535 placedFootprints.
get(),
1539 if (finishedCallback) {
1540 this->addFinishedCallback(std::move(finishedCallback));
1555 "D3DGpu_CreateCompressedBackendTexture");
1582 texture->setResourceState(
this, D3D12_RESOURCE_STATE_COPY_DEST);
1584 ID3D12Resource* d3dResource =
texture->d3dResource();
1586 D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
1587 unsigned int mipLevelCount = 1;
1594 UINT64 combinedBufferSize;
1597 fDevice->GetCopyableFootprints(&desc,
1601 placedFootprints.
get(),
1603 rowSizeInBytes.
get(),
1604 &combinedBufferSize);
1609 combinedBufferSize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
1618 placedFootprints.
get(),
1620 rowSizeInBytes.
get(),
1625 for (
unsigned int i = 0; i < mipLevelCount; ++i) {
1626 placedFootprints[i].Offset += slice.
fOffset;
1633 placedFootprints.
get(),
1637 if (finishedCallback) {
1638 this->addFinishedCallback(std::move(finishedCallback));
1653#if defined(GR_TEST_UTILS)
1654bool GrD3DGpu::isTestingOnlyBackendTexture(
const GrBackendTexture& tex)
const {
1658 if (!tex.getD3DTextureResourceInfo(&
info)) {
1662 if (!textureResource) {
1665 return !(textureResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE);
1672 if (dimensions.
width() > this->caps()->maxRenderTargetSize() ||
1673 dimensions.
height() > this->caps()->maxRenderTargetSize()) {
1680 if (!this->createTextureResourceForBackendSurface(dxgiFormat,
1684 skgpu::Mipmapped::kNo,
1698 if (rt.getD3DTextureResourceInfo(&
info)) {
1705void GrD3DGpu::testingOnly_startCapture() {
1706 if (fGraphicsAnalysis) {
1707 fGraphicsAnalysis->BeginCapture();
1711void GrD3DGpu::testingOnly_stopCapture() {
1712 if (fGraphicsAnalysis) {
1713 fGraphicsAnalysis->EndCapture();
1722 D3D12_RESOURCE_TRANSITION_BARRIER* barriers)
const {
1723 SkASSERT(fCurrentDirectCommandList);
1726 fCurrentDirectCommandList->resourceBarrier(std::move(resource), numBarriers, barriers);
1731 D3D12_RESOURCE_TRANSITION_BARRIER* barriers)
const {
1732 SkASSERT(fCurrentDirectCommandList);
1735 fCurrentDirectCommandList->resourceBarrier(
nullptr, numBarriers, barriers);
1736 fCurrentDirectCommandList->addGrBuffer(sk_ref_sp<const GrBuffer>(
buffer));
1748 if (
GrTexture* tex = proxy->peekTexture()) {
1761 fCurrentDirectCommandList->addGrBuffer(std::move(
buffer));
1766 return this->submitDirectCommandList(SyncQueue::kForce);
1768 return this->submitDirectCommandList(SyncQueue::kSkip);
1780 if (!semaphore.getD3DFenceInfo(&fenceInfo)) {
1790 fQueue->Signal(d3dSem->
fence(), d3dSem->
value());
1797 fQueue->Wait(d3dSem->
fence(), d3dSem->
value());
1801 this->waitForQueueCompletion();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
size_t GrBackendFormatBytesPerPixel(const GrBackendFormat &format)
SkTextureCompressionType GrBackendFormatToCompressionType(const GrBackendFormat &format)
static bool is_bgra(DXGI_FORMAT format)
static void copy_compressed_data(char *mapPtr, DXGI_FORMAT dxgiFormat, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *placedFootprints, UINT *numRows, UINT64 *rowSizeInBytes, const void *compressedData, int numMipLevels)
static bool check_resource_info(const GrD3DTextureResourceInfo &info)
static bool check_rt_resource_info(const GrD3DCaps &caps, const GrD3DTextureResourceInfo &info, int sampleCnt)
static const int kDefaultOutstandingAllocCnt
static int get_surface_sample_cnt(GrSurface *surf)
static bool is_odd(int x)
constexpr int kConstantAlignment
static bool check_tex_resource_info(const GrD3DCaps &caps, const GrD3DTextureResourceInfo &info)
static bool copy_color_data(const GrD3DCaps &caps, char *mapPtr, DXGI_FORMAT dxgiFormat, SkISize dimensions, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *placedFootprints, std::array< float, 4 > color)
bool GrDxgiFormatIsCompressed(DXGI_FORMAT format)
static constexpr size_t GrDxgiFormatBytesPerBlock(DXGI_FORMAT format)
#define GR_D3D_CALL_ERRCHECK(X)
bool GrClearImage(const GrImageInfo &dstInfo, void *dst, size_t dstRB, std::array< float, 4 > color)
static constexpr size_t GrColorTypeBytesPerPixel(GrColorType ct)
@ kDynamic_GrAccessPattern
@ kTopLeft_GrSurfaceOrigin
void * GrGpuFinishedContext
void(* GrGpuFinishedProc)(GrGpuFinishedContext finishedContext)
#define SkAssertResult(cond)
#define SkDEBUGFAIL(message)
size_t SkCompressedFormatDataSize(SkTextureCompressionType compressionType, SkISize dimensions, bool mipmapped)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
#define INHERITED(method,...)
static void SkRectMemcpy(void *dst, size_t dstRB, const void *src, size_t srcRB, size_t trimRowBytes, int rowCount)
sk_sp< T > sk_ref_sp(T *obj)
static constexpr bool SkToBool(const T &x)
GrBackendApi backend() const
SkISize dimensions() const
SkISize dimensions() const
GrBackendApi backend() const
bool mipmapSupport() const
virtual bool isFormatTexturable(const GrBackendFormat &, GrTextureType) const =0
static sk_sp< GrD3DMemoryAllocator > Make(IDXGIAdapter *adapter, ID3D12Device *device)
static sk_sp< GrD3DAttachment > MakeStencil(GrD3DGpu *gpu, SkISize dimensions, int sampleCnt, DXGI_FORMAT format)
ID3D12Resource * d3dResource() const
static sk_sp< GrD3DBuffer > Make(GrD3DGpu *, size_t size, GrGpuBufferType, GrAccessPattern)
GrColorType getFormatColorType(DXGI_FORMAT) const
DXGI_FORMAT getFormatFromColorType(GrColorType colorType) const
bool isFormatRenderable(const GrBackendFormat &format, int sampleCount) const override
DXGI_FORMAT preferredStencilFormat() const
bool canCopyAsResolve(DXGI_FORMAT dstFormat, int dstSampleCnt, DXGI_FORMAT srcFormat, int srcSamplecnt) const
bool isFormatTexturable(const GrBackendFormat &, GrTextureType) const override
int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat &) const override
void addGrBuffer(sk_sp< const GrBuffer > buffer)
void aliasingBarrier(sk_sp< GrManagedResource > beforeManagedResource, ID3D12Resource *beforeResource, sk_sp< GrManagedResource > afterManagedResource, ID3D12Resource *afterResource)
void copyTextureToTexture(const GrD3DTexture *dst, const GrD3DTexture *src, UINT subresourceIndex=-1)
void uavBarrier(sk_sp< GrManagedResource > managedResource, ID3D12Resource *uavResource)
void copyBufferToTexture(ID3D12Resource *srcBuffer, const GrD3DTextureResource *dstTexture, uint32_t subresourceCount, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *bufferFootprints, int left, int top)
void setComputeRootConstantBufferView(unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation)
void addSampledTextureRef(GrD3DTexture *)
void setComputeRootDescriptorTable(unsigned int rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE bufferLocation)
void setDescriptorHeaps(ID3D12DescriptorHeap *srvDescriptorHeap, ID3D12DescriptorHeap *samplerDescriptorHeap)
void setPipelineState(const sk_sp< GrD3DPipeline > &pipeline)
void dispatch(unsigned int threadGroupCountX, unsigned int threadGroupCountY, unsigned int threadGroupCountZ=1)
void setComputeRootSignature(const sk_sp< GrD3DRootSignature > &rootSignature)
sk_sp< GrTexture > onWrapCompressedBackendTexture(const GrBackendTexture &, GrWrapOwnership, GrWrapCacheable) override
void deleteBackendTexture(const GrBackendTexture &) override
bool onRegenerateMipMapLevels(GrTexture *) override
void addBufferResourceBarriers(GrD3DBuffer *buffer, int numBarriers, D3D12_RESOURCE_TRANSITION_BARRIER *barriers) const
GrD3DDirectCommandList * currentCommandList() const
void submit(GrOpsRenderPass *renderPass) override
void insertSemaphore(GrSemaphore *semaphore) override
sk_sp< GrGpuBuffer > onCreateBuffer(size_t sizeInBytes, GrGpuBufferType, GrAccessPattern) override
const GrD3DCaps & d3dCaps() const
bool compile(const GrProgramDesc &, const GrProgramInfo &) override
static std::unique_ptr< GrGpu > Make(const GrD3DBackendContext &backendContext, const GrContextOptions &, GrDirectContext *)
GrOpsRenderPass * onGetOpsRenderPass(GrRenderTarget *, bool useMSAASurface, GrAttachment *, GrSurfaceOrigin, const SkIRect &, const GrOpsRenderPass::LoadAndStoreInfo &, const GrOpsRenderPass::StencilLoadAndStoreInfo &, const skia_private::TArray< GrSurfaceProxy *, true > &sampledProxies, GrXferBarrierFlags renderPassXferBarriers) override
GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat &, skgpu::Mipmapped, GrProtected) override
std::unique_ptr< GrSemaphore > wrapBackendSemaphore(const GrBackendSemaphore &, GrSemaphoreWrapType, GrWrapOwnership) override
bool onTransferFromBufferToBuffer(sk_sp< GrGpuBuffer > src, size_t srcOffset, sk_sp< GrGpuBuffer > dst, size_t dstOffset, size_t size) override
void addFinishedProc(GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext) override
void prepareSurfacesForBackendAccessAndStateUpdates(SkSpan< GrSurfaceProxy * > proxies, SkSurfaces::BackendSurfaceAccess access, const skgpu::MutableTextureState *newState) override
bool onSubmitToGpu(GrSyncCpu sync) override
void waitSemaphore(GrSemaphore *semaphore) override
bool onTransferPixelsFrom(GrSurface *, SkIRect, GrColorType surfaceColorType, GrColorType bufferColorType, sk_sp< GrGpuBuffer >, size_t offset) override
GrD3DMemoryAllocator * memoryAllocator() const
bool onReadPixels(GrSurface *, SkIRect, GrColorType surfaceColorType, GrColorType dstColorType, void *, size_t rowBytes) override
void addResourceBarriers(sk_sp< GrManagedResource > resource, int numBarriers, D3D12_RESOURCE_TRANSITION_BARRIER *barriers) const
void takeOwnershipOfBuffer(sk_sp< GrGpuBuffer >) override
GrBackendTexture onCreateBackendTexture(SkISize dimensions, const GrBackendFormat &, GrRenderable, skgpu::Mipmapped, GrProtected, std::string_view label) override
void onResolveRenderTarget(GrRenderTarget *target, const SkIRect &) override
void endRenderPass(GrRenderTarget *target, GrSurfaceOrigin origin, const SkIRect &bounds)
GrD3DResourceProvider & resourceProvider()
sk_sp< GrThreadSafePipelineBuilder > refPipelineBuilder() override
std::unique_ptr< GrSemaphore > makeSemaphore(bool isOwned) override
GrThreadSafePipelineBuilder * pipelineBuilder() override
bool protectedContext() const
sk_sp< GrTexture > onCreateCompressedTexture(SkISize dimensions, const GrBackendFormat &, skgpu::Budgeted, skgpu::Mipmapped, GrProtected, const void *data, size_t dataSize) override
bool onUpdateCompressedBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, const void *data, size_t size) override
sk_sp< GrTexture > onWrapRenderableBackendTexture(const GrBackendTexture &, int sampleCnt, GrWrapOwnership, GrWrapCacheable) override
sk_sp< GrTexture > onCreateTexture(SkISize, const GrBackendFormat &, GrRenderable, int renderTargetSampleCnt, skgpu::Budgeted, GrProtected, int mipLevelCount, uint32_t levelClearMask, std::string_view label) override
void finishOutstandingGpuWork() override
bool onTransferPixelsTo(GrTexture *, SkIRect, GrColorType surfaceColorType, GrColorType bufferColorType, sk_sp< GrGpuBuffer >, size_t offset, size_t rowBytes) override
sk_sp< GrRenderTarget > onWrapBackendRenderTarget(const GrBackendRenderTarget &) override
bool onCopySurface(GrSurface *dst, const SkIRect &dstRect, GrSurface *src, const SkIRect &srcRect, GrSamplerState::Filter) override
sk_sp< GrAttachment > makeStencilAttachment(const GrBackendFormat &, SkISize dimensions, int numStencilSamples) override
sk_sp< GrTexture > onWrapBackendTexture(const GrBackendTexture &, GrWrapOwnership, GrWrapCacheable, GrIOType) override
bool onWritePixels(GrSurface *, SkIRect, GrColorType surfaceColorType, GrColorType srcColorType, const GrMipLevel[], int mipLevelCount, bool prepForTexSampling) override
bool onClearBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, std::array< float, 4 > color) override
static sk_sp< GrD3DRenderTarget > MakeWrappedRenderTarget(GrD3DGpu *, SkISize, int sampleCnt, const GrD3DTextureResourceInfo &, sk_sp< GrD3DResourceState >)
const GrD3DTextureResource * msaaTextureResource() const
void recycleDirectCommandList(std::unique_ptr< GrD3DDirectCommandList >)
GrD3DDescriptorHeap::CPUHandle createUnorderedAccessView(ID3D12Resource *resource, unsigned int mipSlice)
void recycleShaderView(const GrD3DDescriptorHeap::CPUHandle &)
void markPipelineStateUniformsDirty()
GrD3DDescriptorHeap::CPUHandle createShaderResourceView(ID3D12Resource *resource, unsigned int mostDetailedMip=0, unsigned int mipLevels=-1)
D3D12_GPU_VIRTUAL_ADDRESS uploadConstantData(void *data, size_t size)
sk_sp< GrD3DDescriptorTable > findOrCreateShaderViewTable(const std::vector< D3D12_CPU_DESCRIPTOR_HANDLE > &shaderViews)
D3D12_CPU_DESCRIPTOR_HANDLE findOrCreateCompatibleSampler(const GrSamplerState ¶ms)
sk_sp< GrD3DPipeline > findOrCreateMipmapPipeline()
std::unique_ptr< GrD3DDirectCommandList > findOrCreateDirectCommandList()
sk_sp< GrD3DDescriptorTable > findOrCreateSamplerTable(const std::vector< D3D12_CPU_DESCRIPTOR_HANDLE > &samplers)
sk_sp< GrD3DRootSignature > findOrCreateRootSignature(int numTextureSamplers, int numUAVs=0)
@ kShaderViewDescriptorTable
@ kSamplerDescriptorTable
static std::unique_ptr< GrD3DSemaphore > Make(GrD3DGpu *gpu)
ID3D12Fence * fence() const
static std::unique_ptr< GrD3DSemaphore > MakeWrapped(const GrD3DFenceInfo &)
static sk_sp< GrD3DTextureRenderTarget > MakeWrappedTextureRenderTarget(GrD3DGpu *, SkISize dimensions, int sampleCnt, GrWrapCacheable, const GrD3DTextureResourceInfo &, sk_sp< GrD3DResourceState >)
static sk_sp< GrD3DTextureRenderTarget > MakeNewTextureRenderTarget(GrD3DGpu *, skgpu::Budgeted, SkISize dimensions, int sampleCnt, const D3D12_RESOURCE_DESC &, GrProtected isProtected, GrMipmapStatus, std::string_view label)
DXGI_FORMAT dxgiFormat() const
void prepareForPresent(GrD3DGpu *gpu)
void setResourceState(const GrD3DGpu *gpu, D3D12_RESOURCE_STATES newResourceState, unsigned int subresource=D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES)
ID3D12Resource * d3dResource() const
static bool InitTextureResourceInfo(GrD3DGpu *gpu, const D3D12_RESOURCE_DESC &desc, D3D12_RESOURCE_STATES initialState, GrProtected, D3D12_CLEAR_VALUE *, GrD3DTextureResourceInfo *)
sk_sp< Resource > resource() const
static sk_sp< GrD3DTexture > MakeNewTexture(GrD3DGpu *, skgpu::Budgeted, SkISize dimensions, const D3D12_RESOURCE_DESC &, GrProtected, GrMipmapStatus, std::string_view label)
static sk_sp< GrD3DTexture > MakeAliasingTexture(GrD3DGpu *, sk_sp< GrD3DTexture >, const D3D12_RESOURCE_DESC &newDesc, D3D12_RESOURCE_STATES)
static sk_sp< GrD3DTexture > MakeWrappedTexture(GrD3DGpu *, SkISize dimensions, GrWrapCacheable, GrIOType, const GrD3DTextureResourceInfo &, sk_sp< GrD3DResourceState >)
GrBackendFormat backendFormat() const override
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
void incStencilAttachmentCreates()
bool submitToGpu(GrSyncCpu sync)
const GrCaps * caps() const
GrDirectContext * getContext()
void didWriteToSurface(GrSurface *surface, GrSurfaceOrigin origin, const SkIRect *bounds, uint32_t mipLevels=1) const
Slice allocateStagingBufferSlice(size_t size, size_t requiredAlignment=1)
SkISize dimensions() const
virtual GrRenderTarget * asRenderTarget()
int maxMipmapLevel() const
GrTextureType textureType() const
const void * front() const
const void * back() const
static int ComputeLevelCount(int baseWidth, int baseHeight)
constexpr bool empty() const
static sk_sp< RefCntedCallback > Make(Callback proc, Context ctx)
static const uint8_t buffer[]
uint32_t uint32_t * format
sk_sp< SkBlender > blender SkRect rect
@ kPresent
back-end surface will be used for presenting to screen
gr_cp< ID3D12Device > fDevice
sk_sp< GrD3DMemoryAllocator > fMemoryAllocator
gr_cp< IDXGIAdapter1 > fAdapter
D3D12_CPU_DESCRIPTOR_HANDLE fHandle
gr_cp< ID3D12Resource > fResource
int32_t fBottom
larger y-axis bounds
constexpr SkISize size() const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr int32_t width() const
constexpr SkIPoint topLeft() const
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
bool contains(int32_t x, int32_t y) const
int32_t fRight
larger x-axis bounds
constexpr int32_t width() const
constexpr int32_t height() const